@solana/web3.js 1.70.1 → 1.70.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.70.1",
3
+ "version": "1.70.3",
4
4
  "description": "Solana Javascript API",
5
5
  "keywords": [
6
6
  "api",
@@ -62,6 +62,7 @@
62
62
  "@noble/hashes": "^1.1.2",
63
63
  "@noble/secp256k1": "^1.6.3",
64
64
  "@solana/buffer-layout": "^4.0.0",
65
+ "agentkeepalive": "^4.2.1",
65
66
  "bigint-buffer": "^1.1.5",
66
67
  "bn.js": "^5.0.0",
67
68
  "borsh": "^0.7.0",
package/src/connection.ts CHANGED
@@ -1,9 +1,12 @@
1
+ import HttpKeepAliveAgent, {
2
+ HttpsAgent as HttpsKeepAliveAgent,
3
+ } from 'agentkeepalive';
1
4
  import bs58 from 'bs58';
2
5
  import {Buffer} from 'buffer';
3
6
  // @ts-ignore
4
7
  import fastStableStringify from 'fast-stable-stringify';
5
- import type {Agent as HttpAgent} from 'http';
6
- import {Agent as HttpsAgent} from 'https';
8
+ import type {Agent as NodeHttpAgent} from 'http';
9
+ import {Agent as NodeHttpsAgent} from 'https';
7
10
  import {
8
11
  type as pick,
9
12
  number,
@@ -27,7 +30,6 @@ import {Client as RpcWebSocketClient} from 'rpc-websockets';
27
30
  import RpcClient from 'jayson/lib/client/browser';
28
31
  import {JSONRPCError} from 'jayson';
29
32
 
30
- import {AgentManager} from './agent-manager';
31
33
  import {EpochSchedule} from './epoch-schedule';
32
34
  import {SendTransactionError, SolanaJSONRPCError} from './errors';
33
35
  import fetchImpl, {Response} from './fetch-impl';
@@ -347,6 +349,13 @@ export type BaseTransactionConfirmationStrategy = Readonly<{
347
349
  signature: TransactionSignature;
348
350
  }>;
349
351
 
352
+ /**
353
+ * This type represents all transaction confirmation strategies
354
+ */
355
+ export type TransactionConfirmationStrategy =
356
+ | BlockheightBasedTransactionConfirmationStrategy
357
+ | DurableNonceTransactionConfirmationStrategy;
358
+
350
359
  /* @internal */
351
360
  function assertEndpointUrl(putativeUrl: string) {
352
361
  if (/^https?:/.test(putativeUrl) === false) {
@@ -1452,12 +1461,10 @@ function createRpcClient(
1452
1461
  customFetch?: FetchFn,
1453
1462
  fetchMiddleware?: FetchMiddleware,
1454
1463
  disableRetryOnRateLimit?: boolean,
1455
- httpAgent?: HttpAgent | HttpsAgent | false,
1464
+ httpAgent?: NodeHttpAgent | NodeHttpsAgent | false,
1456
1465
  ): RpcClient {
1457
1466
  const fetch = customFetch ? customFetch : fetchImpl;
1458
- let agentManager:
1459
- | {requestEnd(): void; requestStart(): HttpAgent | HttpsAgent}
1460
- | undefined;
1467
+ let agent: NodeHttpAgent | NodeHttpsAgent | undefined;
1461
1468
  if (process.env.BROWSER) {
1462
1469
  if (httpAgent != null) {
1463
1470
  console.warn(
@@ -1468,21 +1475,30 @@ function createRpcClient(
1468
1475
  } else {
1469
1476
  if (httpAgent == null) {
1470
1477
  if (process.env.NODE_ENV !== 'test') {
1471
- agentManager = new AgentManager(
1472
- url.startsWith('https:') /* useHttps */,
1473
- );
1478
+ const agentOptions = {
1479
+ // One second fewer than the Solana RPC's keepalive timeout.
1480
+ // Read more: https://github.com/solana-labs/solana/issues/27859#issuecomment-1340097889
1481
+ freeSocketTimeout: 19000,
1482
+ keepAlive: true,
1483
+ maxSockets: 25,
1484
+ };
1485
+ if (url.startsWith('https:')) {
1486
+ agent = new HttpsKeepAliveAgent(agentOptions);
1487
+ } else {
1488
+ agent = new HttpKeepAliveAgent(agentOptions);
1489
+ }
1474
1490
  }
1475
1491
  } else {
1476
1492
  if (httpAgent !== false) {
1477
1493
  const isHttps = url.startsWith('https:');
1478
- if (isHttps && !(httpAgent instanceof HttpsAgent)) {
1494
+ if (isHttps && !(httpAgent instanceof NodeHttpsAgent)) {
1479
1495
  throw new Error(
1480
1496
  'The endpoint `' +
1481
1497
  url +
1482
1498
  '` can only be paired with an `https.Agent`. You have, instead, supplied an ' +
1483
1499
  '`http.Agent` through `httpAgent`.',
1484
1500
  );
1485
- } else if (!isHttps && httpAgent instanceof HttpsAgent) {
1501
+ } else if (!isHttps && httpAgent instanceof NodeHttpsAgent) {
1486
1502
  throw new Error(
1487
1503
  'The endpoint `' +
1488
1504
  url +
@@ -1490,7 +1506,7 @@ function createRpcClient(
1490
1506
  '`https.Agent` through `httpAgent`.',
1491
1507
  );
1492
1508
  }
1493
- agentManager = {requestEnd() {}, requestStart: () => httpAgent};
1509
+ agent = httpAgent;
1494
1510
  }
1495
1511
  }
1496
1512
  }
@@ -1515,7 +1531,6 @@ function createRpcClient(
1515
1531
  }
1516
1532
 
1517
1533
  const clientBrowser = new RpcClient(async (request, callback) => {
1518
- const agent = agentManager ? agentManager.requestStart() : undefined;
1519
1534
  const options = {
1520
1535
  method: 'POST',
1521
1536
  body: request,
@@ -1565,8 +1580,6 @@ function createRpcClient(
1565
1580
  }
1566
1581
  } catch (err) {
1567
1582
  if (err instanceof Error) callback(err);
1568
- } finally {
1569
- agentManager && agentManager.requestEnd();
1570
1583
  }
1571
1584
  }, {});
1572
1585
 
@@ -2898,7 +2911,7 @@ export type ConnectionConfig = {
2898
2911
  * persistence). Set this to `false` to create a connection that uses no agent. This applies to
2899
2912
  * Node environments only.
2900
2913
  */
2901
- httpAgent?: HttpAgent | HttpsAgent | false;
2914
+ httpAgent?: NodeHttpAgent | NodeHttpsAgent | false;
2902
2915
  /** Optional commitment level */
2903
2916
  commitment?: Commitment;
2904
2917
  /** Optional endpoint URL to the fullnode JSON RPC PubSub WebSocket Endpoint */
@@ -3597,13 +3610,11 @@ export class Connection {
3597
3610
  }
3598
3611
 
3599
3612
  confirmTransaction(
3600
- strategy:
3601
- | BlockheightBasedTransactionConfirmationStrategy
3602
- | DurableNonceTransactionConfirmationStrategy,
3613
+ strategy: TransactionConfirmationStrategy,
3603
3614
  commitment?: Commitment,
3604
3615
  ): Promise<RpcResponseAndContext<SignatureResult>>;
3605
3616
 
3606
- /** @deprecated Instead, call `confirmTransaction` using a `TransactionConfirmationConfig` */
3617
+ /** @deprecated Instead, call `confirmTransaction` and pass in {@link TransactionConfirmationStrategy} */
3607
3618
  // eslint-disable-next-line no-dupe-class-members
3608
3619
  confirmTransaction(
3609
3620
  strategy: TransactionSignature,
@@ -3612,10 +3623,7 @@ export class Connection {
3612
3623
 
3613
3624
  // eslint-disable-next-line no-dupe-class-members
3614
3625
  async confirmTransaction(
3615
- strategy:
3616
- | BlockheightBasedTransactionConfirmationStrategy
3617
- | DurableNonceTransactionConfirmationStrategy
3618
- | TransactionSignature,
3626
+ strategy: TransactionConfirmationStrategy | TransactionSignature,
3619
3627
  commitment?: Commitment,
3620
3628
  ): Promise<RpcResponseAndContext<SignatureResult>> {
3621
3629
  let rawSignature: string;
@@ -3623,9 +3631,8 @@ export class Connection {
3623
3631
  if (typeof strategy == 'string') {
3624
3632
  rawSignature = strategy;
3625
3633
  } else {
3626
- const config = strategy as
3627
- | BlockheightBasedTransactionConfirmationStrategy
3628
- | DurableNonceTransactionConfirmationStrategy;
3634
+ const config = strategy as TransactionConfirmationStrategy;
3635
+
3629
3636
  if (config.abortSignal?.aborted) {
3630
3637
  return Promise.reject(config.abortSignal.reason);
3631
3638
  }
package/src/publickey.ts CHANGED
@@ -109,14 +109,15 @@ export class PublicKey extends Struct {
109
109
  }
110
110
 
111
111
  /**
112
- * Return the byte array representation of the public key
112
+ * Return the byte array representation of the public key in big endian
113
113
  */
114
114
  toBytes(): Uint8Array {
115
- return this.toBuffer();
115
+ const buf = this.toBuffer();
116
+ return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
116
117
  }
117
118
 
118
119
  /**
119
- * Return the Buffer representation of the public key
120
+ * Return the Buffer representation of the public key in big endian
120
121
  */
121
122
  toBuffer(): Buffer {
122
123
  const b = this._bn.toArrayLike(Buffer);
@@ -4,6 +4,7 @@ import {
4
4
  BlockheightBasedTransactionConfirmationStrategy,
5
5
  Connection,
6
6
  DurableNonceTransactionConfirmationStrategy,
7
+ TransactionConfirmationStrategy,
7
8
  } from '../connection';
8
9
  import type {TransactionSignature} from '../transaction';
9
10
  import type {ConfirmOptions} from '../connection';
@@ -15,14 +16,14 @@ import type {ConfirmOptions} from '../connection';
15
16
  *
16
17
  * @param {Connection} connection
17
18
  * @param {Buffer} rawTransaction
18
- * @param {BlockheightBasedTransactionConfirmationStrategy} confirmationStrategy
19
+ * @param {TransactionConfirmationStrategy} confirmationStrategy
19
20
  * @param {ConfirmOptions} [options]
20
21
  * @returns {Promise<TransactionSignature>}
21
22
  */
22
23
  export async function sendAndConfirmRawTransaction(
23
24
  connection: Connection,
24
25
  rawTransaction: Buffer,
25
- confirmationStrategy: BlockheightBasedTransactionConfirmationStrategy,
26
+ confirmationStrategy: TransactionConfirmationStrategy,
26
27
  options?: ConfirmOptions,
27
28
  ): Promise<TransactionSignature>;
28
29
 
@@ -42,16 +43,12 @@ export async function sendAndConfirmRawTransaction(
42
43
  connection: Connection,
43
44
  rawTransaction: Buffer,
44
45
  confirmationStrategyOrConfirmOptions:
45
- | BlockheightBasedTransactionConfirmationStrategy
46
- | DurableNonceTransactionConfirmationStrategy
46
+ | TransactionConfirmationStrategy
47
47
  | ConfirmOptions
48
48
  | undefined,
49
49
  maybeConfirmOptions?: ConfirmOptions,
50
50
  ): Promise<TransactionSignature> {
51
- let confirmationStrategy:
52
- | BlockheightBasedTransactionConfirmationStrategy
53
- | DurableNonceTransactionConfirmationStrategy
54
- | undefined;
51
+ let confirmationStrategy: TransactionConfirmationStrategy | undefined;
55
52
  let options: ConfirmOptions | undefined;
56
53
  if (
57
54
  confirmationStrategyOrConfirmOptions &&
@@ -1,44 +0,0 @@
1
- import http from 'http';
2
- import https from 'https';
3
-
4
- export const DESTROY_TIMEOUT_MS = 5000;
5
-
6
- export class AgentManager {
7
- _agent: http.Agent | https.Agent;
8
- _activeRequests = 0;
9
- _destroyTimeout: ReturnType<typeof setTimeout> | null = null;
10
- _useHttps: boolean;
11
-
12
- static _newAgent(useHttps: boolean): http.Agent | https.Agent {
13
- const options = {keepAlive: true, maxSockets: 25};
14
- if (useHttps) {
15
- return new https.Agent(options);
16
- } else {
17
- return new http.Agent(options);
18
- }
19
- }
20
-
21
- constructor(useHttps?: boolean) {
22
- this._useHttps = useHttps === true;
23
- this._agent = AgentManager._newAgent(this._useHttps);
24
- }
25
-
26
- requestStart(): http.Agent | https.Agent {
27
- this._activeRequests++;
28
- if (this._destroyTimeout !== null) {
29
- clearTimeout(this._destroyTimeout);
30
- this._destroyTimeout = null;
31
- }
32
- return this._agent;
33
- }
34
-
35
- requestEnd() {
36
- this._activeRequests--;
37
- if (this._activeRequests === 0 && this._destroyTimeout === null) {
38
- this._destroyTimeout = setTimeout(() => {
39
- this._agent.destroy();
40
- this._agent = AgentManager._newAgent(this._useHttps);
41
- }, DESTROY_TIMEOUT_MS);
42
- }
43
- }
44
- }