@solana/web3.js 1.44.3 → 1.47.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.
package/src/connection.ts CHANGED
@@ -26,7 +26,7 @@ import RpcClient from 'jayson/lib/client/browser';
26
26
 
27
27
  import {AgentManager} from './agent-manager';
28
28
  import {EpochSchedule} from './epoch-schedule';
29
- import {SendTransactionError} from './errors';
29
+ import {SendTransactionError, SolanaJSONRPCError} from './errors';
30
30
  import fetchImpl, {Response} from './fetch-impl';
31
31
  import {NonceAccount} from './nonce-account';
32
32
  import {PublicKey} from './publickey';
@@ -228,6 +228,8 @@ export type SendOptions = {
228
228
  preflightCommitment?: Commitment;
229
229
  /** Maximum number of times for the RPC node to retry sending the transaction to the leader. */
230
230
  maxRetries?: number;
231
+ /** The minimum slot that the request can be evaluated at */
232
+ minContextSlot?: number;
231
233
  };
232
234
 
233
235
  /**
@@ -242,6 +244,8 @@ export type ConfirmOptions = {
242
244
  preflightCommitment?: Commitment;
243
245
  /** Maximum number of times for the RPC node to retry sending the transaction to the leader. */
244
246
  maxRetries?: number;
247
+ /** The minimum slot that the request can be evaluated at */
248
+ minContextSlot?: number;
245
249
  };
246
250
 
247
251
  /**
@@ -272,6 +276,8 @@ export type SignaturesForAddressOptions = {
272
276
  until?: TransactionSignature;
273
277
  /** Maximum transaction signatures to return (between 1 and 1,000, default: 1,000). */
274
278
  limit?: number;
279
+ /** The minimum slot that the request can be evaluated at */
280
+ minContextSlot?: number;
275
281
  };
276
282
 
277
283
  /**
@@ -297,6 +303,23 @@ export type BlockheightBasedTransactionConfirmationStrategy = {
297
303
  signature: TransactionSignature;
298
304
  } & BlockhashWithExpiryBlockHeight;
299
305
 
306
+ /** @internal */
307
+ function extractCommitmentFromConfig<TConfig>(
308
+ commitmentOrConfig?: Commitment | ({commitment?: Commitment} & TConfig),
309
+ ) {
310
+ let commitment: Commitment | undefined;
311
+ let config: Omit<TConfig, 'commitment'> | undefined;
312
+ if (typeof commitmentOrConfig === 'string') {
313
+ commitment = commitmentOrConfig;
314
+ } else if (commitmentOrConfig) {
315
+ const {commitment: specifiedCommitment, ...specifiedConfig} =
316
+ commitmentOrConfig;
317
+ commitment = specifiedCommitment;
318
+ config = specifiedConfig;
319
+ }
320
+ return {commitment, config};
321
+ }
322
+
300
323
  /**
301
324
  * @internal
302
325
  */
@@ -399,6 +422,88 @@ export type Finality = 'confirmed' | 'finalized';
399
422
  */
400
423
  export type LargestAccountsFilter = 'circulating' | 'nonCirculating';
401
424
 
425
+ /**
426
+ * Configuration object for changing `getAccountInfo` query behavior
427
+ */
428
+ export type GetAccountInfoConfig = {
429
+ /** The level of commitment desired */
430
+ commitment?: Commitment;
431
+ /** The minimum slot that the request can be evaluated at */
432
+ minContextSlot?: number;
433
+ };
434
+
435
+ /**
436
+ * Configuration object for changing `getBalance` query behavior
437
+ */
438
+ export type GetBalanceConfig = {
439
+ /** The level of commitment desired */
440
+ commitment?: Commitment;
441
+ /** The minimum slot that the request can be evaluated at */
442
+ minContextSlot?: number;
443
+ };
444
+
445
+ /**
446
+ * Configuration object for changing `getBlockHeight` query behavior
447
+ */
448
+ export type GetBlockHeightConfig = {
449
+ /** The level of commitment desired */
450
+ commitment?: Commitment;
451
+ /** The minimum slot that the request can be evaluated at */
452
+ minContextSlot?: number;
453
+ };
454
+
455
+ /**
456
+ * Configuration object for changing `getEpochInfo` query behavior
457
+ */
458
+ export type GetEpochInfoConfig = {
459
+ /** The level of commitment desired */
460
+ commitment?: Commitment;
461
+ /** The minimum slot that the request can be evaluated at */
462
+ minContextSlot?: number;
463
+ };
464
+
465
+ /**
466
+ * Configuration object for changing `getInflationReward` query behavior
467
+ */
468
+ export type GetInflationRewardConfig = {
469
+ /** The level of commitment desired */
470
+ commitment?: Commitment;
471
+ /** An epoch for which the reward occurs. If omitted, the previous epoch will be used */
472
+ epoch?: number;
473
+ /** The minimum slot that the request can be evaluated at */
474
+ minContextSlot?: number;
475
+ };
476
+
477
+ /**
478
+ * Configuration object for changing `getLatestBlockhash` query behavior
479
+ */
480
+ export type GetLatestBlockhashConfig = {
481
+ /** The level of commitment desired */
482
+ commitment?: Commitment;
483
+ /** The minimum slot that the request can be evaluated at */
484
+ minContextSlot?: number;
485
+ };
486
+
487
+ /**
488
+ * Configuration object for changing `getSlot` query behavior
489
+ */
490
+ export type GetSlotConfig = {
491
+ /** The level of commitment desired */
492
+ commitment?: Commitment;
493
+ /** The minimum slot that the request can be evaluated at */
494
+ minContextSlot?: number;
495
+ };
496
+
497
+ /**
498
+ * Configuration object for changing `getSlotLeader` query behavior
499
+ */
500
+ export type GetSlotLeaderConfig = {
501
+ /** The level of commitment desired */
502
+ commitment?: Commitment;
503
+ /** The minimum slot that the request can be evaluated at */
504
+ minContextSlot?: number;
505
+ };
506
+
402
507
  /**
403
508
  * Configuration object for changing `getLargestAccounts` query behavior
404
509
  */
@@ -995,6 +1100,7 @@ function createRpcClient(
995
1100
  'Content-Type': 'application/json',
996
1101
  },
997
1102
  httpHeaders || {},
1103
+ COMMON_HTTP_HEADERS,
998
1104
  ),
999
1105
  };
1000
1106
 
@@ -1948,6 +2054,8 @@ export type GetProgramAccountsConfig = {
1948
2054
  dataSlice?: DataSlice;
1949
2055
  /** Optional array of filters to apply to accounts */
1950
2056
  filters?: GetProgramAccountsFilter[];
2057
+ /** The minimum slot that the request can be evaluated at */
2058
+ minContextSlot?: number;
1951
2059
  };
1952
2060
 
1953
2061
  /**
@@ -1958,6 +2066,8 @@ export type GetParsedProgramAccountsConfig = {
1958
2066
  commitment?: Commitment;
1959
2067
  /** Optional array of filters to apply to accounts */
1960
2068
  filters?: GetProgramAccountsFilter[];
2069
+ /** The minimum slot that the request can be evaluated at */
2070
+ minContextSlot?: number;
1961
2071
  };
1962
2072
 
1963
2073
  /**
@@ -1966,8 +2076,40 @@ export type GetParsedProgramAccountsConfig = {
1966
2076
  export type GetMultipleAccountsConfig = {
1967
2077
  /** Optional commitment level */
1968
2078
  commitment?: Commitment;
1969
- /** Optional encoding for account data (default base64) */
1970
- encoding?: 'base64' | 'jsonParsed';
2079
+ /** The minimum slot that the request can be evaluated at */
2080
+ minContextSlot?: number;
2081
+ };
2082
+
2083
+ /**
2084
+ * Configuration object for `getStakeActivation`
2085
+ */
2086
+ export type GetStakeActivationConfig = {
2087
+ /** Optional commitment level */
2088
+ commitment?: Commitment;
2089
+ /** Epoch for which to calculate activation details. If parameter not provided, defaults to current epoch */
2090
+ epoch?: number;
2091
+ /** The minimum slot that the request can be evaluated at */
2092
+ minContextSlot?: number;
2093
+ };
2094
+
2095
+ /**
2096
+ * Configuration object for `getStakeActivation`
2097
+ */
2098
+ export type GetTokenAccountsByOwnerConfig = {
2099
+ /** Optional commitment level */
2100
+ commitment?: Commitment;
2101
+ /** The minimum slot that the request can be evaluated at */
2102
+ minContextSlot?: number;
2103
+ };
2104
+
2105
+ /**
2106
+ * Configuration object for `getStakeActivation`
2107
+ */
2108
+ export type GetTransactionCountConfig = {
2109
+ /** Optional commitment level */
2110
+ commitment?: Commitment;
2111
+ /** The minimum slot that the request can be evaluated at */
2112
+ minContextSlot?: number;
1971
2113
  };
1972
2114
 
1973
2115
  /**
@@ -2158,7 +2300,12 @@ export type ConfirmedSignatureInfo = {
2158
2300
  /**
2159
2301
  * An object defining headers to be passed to the RPC server
2160
2302
  */
2161
- export type HttpHeaders = {[header: string]: string};
2303
+ export type HttpHeaders = {
2304
+ [header: string]: string;
2305
+ } & {
2306
+ // Prohibited headers; for internal use only.
2307
+ 'solana-client'?: never;
2308
+ };
2162
2309
 
2163
2310
  /**
2164
2311
  * The type of the JavaScript `fetch()` API
@@ -2194,6 +2341,11 @@ export type ConnectionConfig = {
2194
2341
  confirmTransactionInitialTimeout?: number;
2195
2342
  };
2196
2343
 
2344
+ /** @internal */
2345
+ const COMMON_HTTP_HEADERS = {
2346
+ 'solana-client': `js/${process.env.npm_package_version ?? 'UNKNOWN'}`,
2347
+ };
2348
+
2197
2349
  /**
2198
2350
  * A connection to a fullnode JSON RPC endpoint
2199
2351
  */
@@ -2366,17 +2518,23 @@ export class Connection {
2366
2518
  */
2367
2519
  async getBalanceAndContext(
2368
2520
  publicKey: PublicKey,
2369
- commitment?: Commitment,
2521
+ commitmentOrConfig?: Commitment | GetBalanceConfig,
2370
2522
  ): Promise<RpcResponseAndContext<number>> {
2371
- const args = this._buildArgs([publicKey.toBase58()], commitment);
2523
+ /** @internal */
2524
+ const {commitment, config} =
2525
+ extractCommitmentFromConfig(commitmentOrConfig);
2526
+ const args = this._buildArgs(
2527
+ [publicKey.toBase58()],
2528
+ commitment,
2529
+ undefined /* encoding */,
2530
+ config,
2531
+ );
2372
2532
  const unsafeRes = await this._rpcRequest('getBalance', args);
2373
2533
  const res = create(unsafeRes, jsonRpcResultAndContext(number()));
2374
2534
  if ('error' in res) {
2375
- throw new Error(
2376
- 'failed to get balance for ' +
2377
- publicKey.toBase58() +
2378
- ': ' +
2379
- res.error.message,
2535
+ throw new SolanaJSONRPCError(
2536
+ res.error,
2537
+ `failed to get balance for ${publicKey.toBase58()}`,
2380
2538
  );
2381
2539
  }
2382
2540
  return res.result;
@@ -2387,9 +2545,9 @@ export class Connection {
2387
2545
  */
2388
2546
  async getBalance(
2389
2547
  publicKey: PublicKey,
2390
- commitment?: Commitment,
2548
+ commitmentOrConfig?: Commitment | GetBalanceConfig,
2391
2549
  ): Promise<number> {
2392
- return await this.getBalanceAndContext(publicKey, commitment)
2550
+ return await this.getBalanceAndContext(publicKey, commitmentOrConfig)
2393
2551
  .then(x => x.value)
2394
2552
  .catch(e => {
2395
2553
  throw new Error(
@@ -2405,8 +2563,9 @@ export class Connection {
2405
2563
  const unsafeRes = await this._rpcRequest('getBlockTime', [slot]);
2406
2564
  const res = create(unsafeRes, jsonRpcResult(nullable(number())));
2407
2565
  if ('error' in res) {
2408
- throw new Error(
2409
- 'failed to get block time for slot ' + slot + ': ' + res.error.message,
2566
+ throw new SolanaJSONRPCError(
2567
+ res.error,
2568
+ `failed to get block time for slot ${slot}`,
2410
2569
  );
2411
2570
  }
2412
2571
  return res.result;
@@ -2420,8 +2579,9 @@ export class Connection {
2420
2579
  const unsafeRes = await this._rpcRequest('minimumLedgerSlot', []);
2421
2580
  const res = create(unsafeRes, jsonRpcResult(number()));
2422
2581
  if ('error' in res) {
2423
- throw new Error(
2424
- 'failed to get minimum ledger slot: ' + res.error.message,
2582
+ throw new SolanaJSONRPCError(
2583
+ res.error,
2584
+ 'failed to get minimum ledger slot',
2425
2585
  );
2426
2586
  }
2427
2587
  return res.result;
@@ -2434,8 +2594,9 @@ export class Connection {
2434
2594
  const unsafeRes = await this._rpcRequest('getFirstAvailableBlock', []);
2435
2595
  const res = create(unsafeRes, SlotRpcResult);
2436
2596
  if ('error' in res) {
2437
- throw new Error(
2438
- 'failed to get first available block: ' + res.error.message,
2597
+ throw new SolanaJSONRPCError(
2598
+ res.error,
2599
+ 'failed to get first available block',
2439
2600
  );
2440
2601
  }
2441
2602
  return res.result;
@@ -2464,7 +2625,7 @@ export class Connection {
2464
2625
  const unsafeRes = await this._rpcRequest('getSupply', [configArg]);
2465
2626
  const res = create(unsafeRes, GetSupplyRpcResult);
2466
2627
  if ('error' in res) {
2467
- throw new Error('failed to get supply: ' + res.error.message);
2628
+ throw new SolanaJSONRPCError(res.error, 'failed to get supply');
2468
2629
  }
2469
2630
  return res.result;
2470
2631
  }
@@ -2480,7 +2641,7 @@ export class Connection {
2480
2641
  const unsafeRes = await this._rpcRequest('getTokenSupply', args);
2481
2642
  const res = create(unsafeRes, jsonRpcResultAndContext(TokenAmountResult));
2482
2643
  if ('error' in res) {
2483
- throw new Error('failed to get token supply: ' + res.error.message);
2644
+ throw new SolanaJSONRPCError(res.error, 'failed to get token supply');
2484
2645
  }
2485
2646
  return res.result;
2486
2647
  }
@@ -2496,8 +2657,9 @@ export class Connection {
2496
2657
  const unsafeRes = await this._rpcRequest('getTokenAccountBalance', args);
2497
2658
  const res = create(unsafeRes, jsonRpcResultAndContext(TokenAmountResult));
2498
2659
  if ('error' in res) {
2499
- throw new Error(
2500
- 'failed to get token account balance: ' + res.error.message,
2660
+ throw new SolanaJSONRPCError(
2661
+ res.error,
2662
+ 'failed to get token account balance',
2501
2663
  );
2502
2664
  }
2503
2665
  return res.result;
@@ -2511,12 +2673,14 @@ export class Connection {
2511
2673
  async getTokenAccountsByOwner(
2512
2674
  ownerAddress: PublicKey,
2513
2675
  filter: TokenAccountsFilter,
2514
- commitment?: Commitment,
2676
+ commitmentOrConfig?: Commitment | GetTokenAccountsByOwnerConfig,
2515
2677
  ): Promise<
2516
2678
  RpcResponseAndContext<
2517
2679
  Array<{pubkey: PublicKey; account: AccountInfo<Buffer>}>
2518
2680
  >
2519
2681
  > {
2682
+ const {commitment, config} =
2683
+ extractCommitmentFromConfig(commitmentOrConfig);
2520
2684
  let _args: any[] = [ownerAddress.toBase58()];
2521
2685
  if ('mint' in filter) {
2522
2686
  _args.push({mint: filter.mint.toBase58()});
@@ -2524,15 +2688,13 @@ export class Connection {
2524
2688
  _args.push({programId: filter.programId.toBase58()});
2525
2689
  }
2526
2690
 
2527
- const args = this._buildArgs(_args, commitment, 'base64');
2691
+ const args = this._buildArgs(_args, commitment, 'base64', config);
2528
2692
  const unsafeRes = await this._rpcRequest('getTokenAccountsByOwner', args);
2529
2693
  const res = create(unsafeRes, GetTokenAccountsByOwner);
2530
2694
  if ('error' in res) {
2531
- throw new Error(
2532
- 'failed to get token accounts owned by account ' +
2533
- ownerAddress.toBase58() +
2534
- ': ' +
2535
- res.error.message,
2695
+ throw new SolanaJSONRPCError(
2696
+ res.error,
2697
+ `failed to get token accounts owned by account ${ownerAddress.toBase58()}`,
2536
2698
  );
2537
2699
  }
2538
2700
  return res.result;
@@ -2563,11 +2725,9 @@ export class Connection {
2563
2725
  const unsafeRes = await this._rpcRequest('getTokenAccountsByOwner', args);
2564
2726
  const res = create(unsafeRes, GetParsedTokenAccountsByOwner);
2565
2727
  if ('error' in res) {
2566
- throw new Error(
2567
- 'failed to get token accounts owned by account ' +
2568
- ownerAddress.toBase58() +
2569
- ': ' +
2570
- res.error.message,
2728
+ throw new SolanaJSONRPCError(
2729
+ res.error,
2730
+ `failed to get token accounts owned by account ${ownerAddress.toBase58()}`,
2571
2731
  );
2572
2732
  }
2573
2733
  return res.result;
@@ -2587,7 +2747,7 @@ export class Connection {
2587
2747
  const unsafeRes = await this._rpcRequest('getLargestAccounts', args);
2588
2748
  const res = create(unsafeRes, GetLargestAccountsRpcResult);
2589
2749
  if ('error' in res) {
2590
- throw new Error('failed to get largest accounts: ' + res.error.message);
2750
+ throw new SolanaJSONRPCError(res.error, 'failed to get largest accounts');
2591
2751
  }
2592
2752
  return res.result;
2593
2753
  }
@@ -2604,8 +2764,9 @@ export class Connection {
2604
2764
  const unsafeRes = await this._rpcRequest('getTokenLargestAccounts', args);
2605
2765
  const res = create(unsafeRes, GetTokenLargestAccountsResult);
2606
2766
  if ('error' in res) {
2607
- throw new Error(
2608
- 'failed to get token largest accounts: ' + res.error.message,
2767
+ throw new SolanaJSONRPCError(
2768
+ res.error,
2769
+ 'failed to get token largest accounts',
2609
2770
  );
2610
2771
  }
2611
2772
  return res.result;
@@ -2616,20 +2777,25 @@ export class Connection {
2616
2777
  */
2617
2778
  async getAccountInfoAndContext(
2618
2779
  publicKey: PublicKey,
2619
- commitment?: Commitment,
2780
+ commitmentOrConfig?: Commitment | GetAccountInfoConfig,
2620
2781
  ): Promise<RpcResponseAndContext<AccountInfo<Buffer> | null>> {
2621
- const args = this._buildArgs([publicKey.toBase58()], commitment, 'base64');
2782
+ const {commitment, config} =
2783
+ extractCommitmentFromConfig(commitmentOrConfig);
2784
+ const args = this._buildArgs(
2785
+ [publicKey.toBase58()],
2786
+ commitment,
2787
+ 'base64',
2788
+ config,
2789
+ );
2622
2790
  const unsafeRes = await this._rpcRequest('getAccountInfo', args);
2623
2791
  const res = create(
2624
2792
  unsafeRes,
2625
2793
  jsonRpcResultAndContext(nullable(AccountInfoResult)),
2626
2794
  );
2627
2795
  if ('error' in res) {
2628
- throw new Error(
2629
- 'failed to get info about account ' +
2630
- publicKey.toBase58() +
2631
- ': ' +
2632
- res.error.message,
2796
+ throw new SolanaJSONRPCError(
2797
+ res.error,
2798
+ `failed to get info about account ${publicKey.toBase58()}`,
2633
2799
  );
2634
2800
  }
2635
2801
  return res.result;
@@ -2655,11 +2821,9 @@ export class Connection {
2655
2821
  jsonRpcResultAndContext(nullable(ParsedAccountInfoResult)),
2656
2822
  );
2657
2823
  if ('error' in res) {
2658
- throw new Error(
2659
- 'failed to get info about account ' +
2660
- publicKey.toBase58() +
2661
- ': ' +
2662
- res.error.message,
2824
+ throw new SolanaJSONRPCError(
2825
+ res.error,
2826
+ `failed to get info about account ${publicKey.toBase58()}`,
2663
2827
  );
2664
2828
  }
2665
2829
  return res.result;
@@ -2670,10 +2834,13 @@ export class Connection {
2670
2834
  */
2671
2835
  async getAccountInfo(
2672
2836
  publicKey: PublicKey,
2673
- commitment?: Commitment,
2837
+ commitmentOrConfig?: Commitment | GetAccountInfoConfig,
2674
2838
  ): Promise<AccountInfo<Buffer> | null> {
2675
2839
  try {
2676
- const res = await this.getAccountInfoAndContext(publicKey, commitment);
2840
+ const res = await this.getAccountInfoAndContext(
2841
+ publicKey,
2842
+ commitmentOrConfig,
2843
+ );
2677
2844
  return res.value;
2678
2845
  } catch (e) {
2679
2846
  throw new Error(
@@ -2687,18 +2854,21 @@ export class Connection {
2687
2854
  */
2688
2855
  async getMultipleAccountsInfoAndContext(
2689
2856
  publicKeys: PublicKey[],
2690
- commitment?: Commitment,
2857
+ commitmentOrConfig?: Commitment | GetMultipleAccountsConfig,
2691
2858
  ): Promise<RpcResponseAndContext<(AccountInfo<Buffer> | null)[]>> {
2859
+ const {commitment, config} =
2860
+ extractCommitmentFromConfig(commitmentOrConfig);
2692
2861
  const keys = publicKeys.map(key => key.toBase58());
2693
- const args = this._buildArgs([keys], commitment, 'base64');
2862
+ const args = this._buildArgs([keys], commitment, 'base64', config);
2694
2863
  const unsafeRes = await this._rpcRequest('getMultipleAccounts', args);
2695
2864
  const res = create(
2696
2865
  unsafeRes,
2697
2866
  jsonRpcResultAndContext(array(nullable(AccountInfoResult))),
2698
2867
  );
2699
2868
  if ('error' in res) {
2700
- throw new Error(
2701
- 'failed to get info for accounts ' + keys + ': ' + res.error.message,
2869
+ throw new SolanaJSONRPCError(
2870
+ res.error,
2871
+ `failed to get info for accounts ${keys}`,
2702
2872
  );
2703
2873
  }
2704
2874
  return res.result;
@@ -2709,11 +2879,11 @@ export class Connection {
2709
2879
  */
2710
2880
  async getMultipleAccountsInfo(
2711
2881
  publicKeys: PublicKey[],
2712
- commitment?: Commitment,
2882
+ commitmentOrConfig?: Commitment | GetMultipleAccountsConfig,
2713
2883
  ): Promise<(AccountInfo<Buffer> | null)[]> {
2714
2884
  const res = await this.getMultipleAccountsInfoAndContext(
2715
2885
  publicKeys,
2716
- commitment,
2886
+ commitmentOrConfig,
2717
2887
  );
2718
2888
  return res.value;
2719
2889
  }
@@ -2723,23 +2893,27 @@ export class Connection {
2723
2893
  */
2724
2894
  async getStakeActivation(
2725
2895
  publicKey: PublicKey,
2726
- commitment?: Commitment,
2896
+ commitmentOrConfig?: Commitment | GetStakeActivationConfig,
2727
2897
  epoch?: number,
2728
2898
  ): Promise<StakeActivationData> {
2899
+ const {commitment, config} =
2900
+ extractCommitmentFromConfig(commitmentOrConfig);
2729
2901
  const args = this._buildArgs(
2730
2902
  [publicKey.toBase58()],
2731
2903
  commitment,
2732
- undefined,
2733
- epoch !== undefined ? {epoch} : undefined,
2904
+ undefined /* encoding */,
2905
+ {
2906
+ ...config,
2907
+ epoch: epoch != null ? epoch : config?.epoch,
2908
+ },
2734
2909
  );
2735
2910
 
2736
2911
  const unsafeRes = await this._rpcRequest('getStakeActivation', args);
2737
2912
  const res = create(unsafeRes, jsonRpcResult(StakeActivationResult));
2738
2913
  if ('error' in res) {
2739
- throw new Error(
2740
- `failed to get Stake Activation ${publicKey.toBase58()}: ${
2741
- res.error.message
2742
- }`,
2914
+ throw new SolanaJSONRPCError(
2915
+ res.error,
2916
+ `failed to get Stake Activation ${publicKey.toBase58()}`,
2743
2917
  );
2744
2918
  }
2745
2919
  return res.result;
@@ -2754,40 +2928,21 @@ export class Connection {
2754
2928
  programId: PublicKey,
2755
2929
  configOrCommitment?: GetProgramAccountsConfig | Commitment,
2756
2930
  ): Promise<Array<{pubkey: PublicKey; account: AccountInfo<Buffer>}>> {
2757
- const extra: Pick<GetProgramAccountsConfig, 'dataSlice' | 'filters'> = {};
2758
-
2759
- let commitment;
2760
- let encoding;
2761
- if (configOrCommitment) {
2762
- if (typeof configOrCommitment === 'string') {
2763
- commitment = configOrCommitment;
2764
- } else {
2765
- commitment = configOrCommitment.commitment;
2766
- encoding = configOrCommitment.encoding;
2767
-
2768
- if (configOrCommitment.dataSlice) {
2769
- extra.dataSlice = configOrCommitment.dataSlice;
2770
- }
2771
- if (configOrCommitment.filters) {
2772
- extra.filters = configOrCommitment.filters;
2773
- }
2774
- }
2775
- }
2776
-
2931
+ const {commitment, config} =
2932
+ extractCommitmentFromConfig(configOrCommitment);
2933
+ const {encoding, ...configWithoutEncoding} = config || {};
2777
2934
  const args = this._buildArgs(
2778
2935
  [programId.toBase58()],
2779
2936
  commitment,
2780
2937
  encoding || 'base64',
2781
- extra,
2938
+ configWithoutEncoding,
2782
2939
  );
2783
2940
  const unsafeRes = await this._rpcRequest('getProgramAccounts', args);
2784
2941
  const res = create(unsafeRes, jsonRpcResult(array(KeyedAccountInfoResult)));
2785
2942
  if ('error' in res) {
2786
- throw new Error(
2787
- 'failed to get accounts owned by program ' +
2788
- programId.toBase58() +
2789
- ': ' +
2790
- res.error.message,
2943
+ throw new SolanaJSONRPCError(
2944
+ res.error,
2945
+ `failed to get accounts owned by program ${programId.toBase58()}`,
2791
2946
  );
2792
2947
  }
2793
2948
  return res.result;
@@ -2807,26 +2962,13 @@ export class Connection {
2807
2962
  account: AccountInfo<Buffer | ParsedAccountData>;
2808
2963
  }>
2809
2964
  > {
2810
- const extra: Pick<GetParsedProgramAccountsConfig, 'filters'> = {};
2811
-
2812
- let commitment;
2813
- if (configOrCommitment) {
2814
- if (typeof configOrCommitment === 'string') {
2815
- commitment = configOrCommitment;
2816
- } else {
2817
- commitment = configOrCommitment.commitment;
2818
-
2819
- if (configOrCommitment.filters) {
2820
- extra.filters = configOrCommitment.filters;
2821
- }
2822
- }
2823
- }
2824
-
2965
+ const {commitment, config} =
2966
+ extractCommitmentFromConfig(configOrCommitment);
2825
2967
  const args = this._buildArgs(
2826
2968
  [programId.toBase58()],
2827
2969
  commitment,
2828
2970
  'jsonParsed',
2829
- extra,
2971
+ config,
2830
2972
  );
2831
2973
  const unsafeRes = await this._rpcRequest('getProgramAccounts', args);
2832
2974
  const res = create(
@@ -2834,11 +2976,9 @@ export class Connection {
2834
2976
  jsonRpcResult(array(KeyedParsedAccountInfoResult)),
2835
2977
  );
2836
2978
  if ('error' in res) {
2837
- throw new Error(
2838
- 'failed to get accounts owned by program ' +
2839
- programId.toBase58() +
2840
- ': ' +
2841
- res.error.message,
2979
+ throw new SolanaJSONRPCError(
2980
+ res.error,
2981
+ `failed to get accounts owned by program ${programId.toBase58()}`,
2842
2982
  );
2843
2983
  }
2844
2984
  return res.result;
@@ -2993,7 +3133,7 @@ export class Connection {
2993
3133
  const unsafeRes = await this._rpcRequest('getClusterNodes', []);
2994
3134
  const res = create(unsafeRes, jsonRpcResult(array(ContactInfoResult)));
2995
3135
  if ('error' in res) {
2996
- throw new Error('failed to get cluster nodes: ' + res.error.message);
3136
+ throw new SolanaJSONRPCError(res.error, 'failed to get cluster nodes');
2997
3137
  }
2998
3138
  return res.result;
2999
3139
  }
@@ -3006,7 +3146,7 @@ export class Connection {
3006
3146
  const unsafeRes = await this._rpcRequest('getVoteAccounts', args);
3007
3147
  const res = create(unsafeRes, GetVoteAccounts);
3008
3148
  if ('error' in res) {
3009
- throw new Error('failed to get vote accounts: ' + res.error.message);
3149
+ throw new SolanaJSONRPCError(res.error, 'failed to get vote accounts');
3010
3150
  }
3011
3151
  return res.result;
3012
3152
  }
@@ -3014,12 +3154,21 @@ export class Connection {
3014
3154
  /**
3015
3155
  * Fetch the current slot that the node is processing
3016
3156
  */
3017
- async getSlot(commitment?: Commitment): Promise<number> {
3018
- const args = this._buildArgs([], commitment);
3157
+ async getSlot(
3158
+ commitmentOrConfig?: Commitment | GetSlotConfig,
3159
+ ): Promise<number> {
3160
+ const {commitment, config} =
3161
+ extractCommitmentFromConfig(commitmentOrConfig);
3162
+ const args = this._buildArgs(
3163
+ [],
3164
+ commitment,
3165
+ undefined /* encoding */,
3166
+ config,
3167
+ );
3019
3168
  const unsafeRes = await this._rpcRequest('getSlot', args);
3020
3169
  const res = create(unsafeRes, jsonRpcResult(number()));
3021
3170
  if ('error' in res) {
3022
- throw new Error('failed to get slot: ' + res.error.message);
3171
+ throw new SolanaJSONRPCError(res.error, 'failed to get slot');
3023
3172
  }
3024
3173
  return res.result;
3025
3174
  }
@@ -3027,12 +3176,21 @@ export class Connection {
3027
3176
  /**
3028
3177
  * Fetch the current slot leader of the cluster
3029
3178
  */
3030
- async getSlotLeader(commitment?: Commitment): Promise<string> {
3031
- const args = this._buildArgs([], commitment);
3179
+ async getSlotLeader(
3180
+ commitmentOrConfig?: Commitment | GetSlotLeaderConfig,
3181
+ ): Promise<string> {
3182
+ const {commitment, config} =
3183
+ extractCommitmentFromConfig(commitmentOrConfig);
3184
+ const args = this._buildArgs(
3185
+ [],
3186
+ commitment,
3187
+ undefined /* encoding */,
3188
+ config,
3189
+ );
3032
3190
  const unsafeRes = await this._rpcRequest('getSlotLeader', args);
3033
3191
  const res = create(unsafeRes, jsonRpcResult(string()));
3034
3192
  if ('error' in res) {
3035
- throw new Error('failed to get slot leader: ' + res.error.message);
3193
+ throw new SolanaJSONRPCError(res.error, 'failed to get slot leader');
3036
3194
  }
3037
3195
  return res.result;
3038
3196
  }
@@ -3051,7 +3209,7 @@ export class Connection {
3051
3209
  const unsafeRes = await this._rpcRequest('getSlotLeaders', args);
3052
3210
  const res = create(unsafeRes, jsonRpcResult(array(PublicKeyFromString)));
3053
3211
  if ('error' in res) {
3054
- throw new Error('failed to get slot leaders: ' + res.error.message);
3212
+ throw new SolanaJSONRPCError(res.error, 'failed to get slot leaders');
3055
3213
  }
3056
3214
  return res.result;
3057
3215
  }
@@ -3086,7 +3244,7 @@ export class Connection {
3086
3244
  const unsafeRes = await this._rpcRequest('getSignatureStatuses', params);
3087
3245
  const res = create(unsafeRes, GetSignatureStatusesRpcResult);
3088
3246
  if ('error' in res) {
3089
- throw new Error('failed to get signature status: ' + res.error.message);
3247
+ throw new SolanaJSONRPCError(res.error, 'failed to get signature status');
3090
3248
  }
3091
3249
  return res.result;
3092
3250
  }
@@ -3094,12 +3252,24 @@ export class Connection {
3094
3252
  /**
3095
3253
  * Fetch the current transaction count of the cluster
3096
3254
  */
3097
- async getTransactionCount(commitment?: Commitment): Promise<number> {
3098
- const args = this._buildArgs([], commitment);
3255
+ async getTransactionCount(
3256
+ commitmentOrConfig?: Commitment | GetTransactionCountConfig,
3257
+ ): Promise<number> {
3258
+ const {commitment, config} =
3259
+ extractCommitmentFromConfig(commitmentOrConfig);
3260
+ const args = this._buildArgs(
3261
+ [],
3262
+ commitment,
3263
+ undefined /* encoding */,
3264
+ config,
3265
+ );
3099
3266
  const unsafeRes = await this._rpcRequest('getTransactionCount', args);
3100
3267
  const res = create(unsafeRes, jsonRpcResult(number()));
3101
3268
  if ('error' in res) {
3102
- throw new Error('failed to get transaction count: ' + res.error.message);
3269
+ throw new SolanaJSONRPCError(
3270
+ res.error,
3271
+ 'failed to get transaction count',
3272
+ );
3103
3273
  }
3104
3274
  return res.result;
3105
3275
  }
@@ -3127,7 +3297,7 @@ export class Connection {
3127
3297
  const unsafeRes = await this._rpcRequest('getInflationGovernor', args);
3128
3298
  const res = create(unsafeRes, GetInflationGovernorRpcResult);
3129
3299
  if ('error' in res) {
3130
- throw new Error('failed to get inflation: ' + res.error.message);
3300
+ throw new SolanaJSONRPCError(res.error, 'failed to get inflation');
3131
3301
  }
3132
3302
  return res.result;
3133
3303
  }
@@ -3138,20 +3308,23 @@ export class Connection {
3138
3308
  async getInflationReward(
3139
3309
  addresses: PublicKey[],
3140
3310
  epoch?: number,
3141
- commitment?: Commitment,
3311
+ commitmentOrConfig?: Commitment | GetInflationRewardConfig,
3142
3312
  ): Promise<(InflationReward | null)[]> {
3313
+ const {commitment, config} =
3314
+ extractCommitmentFromConfig(commitmentOrConfig);
3143
3315
  const args = this._buildArgs(
3144
3316
  [addresses.map(pubkey => pubkey.toBase58())],
3145
3317
  commitment,
3146
- undefined,
3318
+ undefined /* encoding */,
3147
3319
  {
3148
- epoch,
3320
+ ...config,
3321
+ epoch: epoch != null ? epoch : config?.epoch,
3149
3322
  },
3150
3323
  );
3151
3324
  const unsafeRes = await this._rpcRequest('getInflationReward', args);
3152
3325
  const res = create(unsafeRes, GetInflationRewardResult);
3153
3326
  if ('error' in res) {
3154
- throw new Error('failed to get inflation reward: ' + res.error.message);
3327
+ throw new SolanaJSONRPCError(res.error, 'failed to get inflation reward');
3155
3328
  }
3156
3329
  return res.result;
3157
3330
  }
@@ -3159,12 +3332,21 @@ export class Connection {
3159
3332
  /**
3160
3333
  * Fetch the Epoch Info parameters
3161
3334
  */
3162
- async getEpochInfo(commitment?: Commitment): Promise<EpochInfo> {
3163
- const args = this._buildArgs([], commitment);
3335
+ async getEpochInfo(
3336
+ commitmentOrConfig?: Commitment | GetEpochInfoConfig,
3337
+ ): Promise<EpochInfo> {
3338
+ const {commitment, config} =
3339
+ extractCommitmentFromConfig(commitmentOrConfig);
3340
+ const args = this._buildArgs(
3341
+ [],
3342
+ commitment,
3343
+ undefined /* encoding */,
3344
+ config,
3345
+ );
3164
3346
  const unsafeRes = await this._rpcRequest('getEpochInfo', args);
3165
3347
  const res = create(unsafeRes, GetEpochInfoRpcResult);
3166
3348
  if ('error' in res) {
3167
- throw new Error('failed to get epoch info: ' + res.error.message);
3349
+ throw new SolanaJSONRPCError(res.error, 'failed to get epoch info');
3168
3350
  }
3169
3351
  return res.result;
3170
3352
  }
@@ -3176,7 +3358,7 @@ export class Connection {
3176
3358
  const unsafeRes = await this._rpcRequest('getEpochSchedule', []);
3177
3359
  const res = create(unsafeRes, GetEpochScheduleRpcResult);
3178
3360
  if ('error' in res) {
3179
- throw new Error('failed to get epoch schedule: ' + res.error.message);
3361
+ throw new SolanaJSONRPCError(res.error, 'failed to get epoch schedule');
3180
3362
  }
3181
3363
  const epochSchedule = res.result;
3182
3364
  return new EpochSchedule(
@@ -3196,7 +3378,7 @@ export class Connection {
3196
3378
  const unsafeRes = await this._rpcRequest('getLeaderSchedule', []);
3197
3379
  const res = create(unsafeRes, GetLeaderScheduleRpcResult);
3198
3380
  if ('error' in res) {
3199
- throw new Error('failed to get leader schedule: ' + res.error.message);
3381
+ throw new SolanaJSONRPCError(res.error, 'failed to get leader schedule');
3200
3382
  }
3201
3383
  return res.result;
3202
3384
  }
@@ -3237,7 +3419,7 @@ export class Connection {
3237
3419
  const unsafeRes = await this._rpcRequest('getRecentBlockhash', args);
3238
3420
  const res = create(unsafeRes, GetRecentBlockhashAndContextRpcResult);
3239
3421
  if ('error' in res) {
3240
- throw new Error('failed to get recent blockhash: ' + res.error.message);
3422
+ throw new SolanaJSONRPCError(res.error, 'failed to get recent blockhash');
3241
3423
  }
3242
3424
  return res.result;
3243
3425
  }
@@ -3256,8 +3438,9 @@ export class Connection {
3256
3438
  );
3257
3439
  const res = create(unsafeRes, GetRecentPerformanceSamplesRpcResult);
3258
3440
  if ('error' in res) {
3259
- throw new Error(
3260
- 'failed to get recent performance samples: ' + res.error.message,
3441
+ throw new SolanaJSONRPCError(
3442
+ res.error,
3443
+ 'failed to get recent performance samples',
3261
3444
  );
3262
3445
  }
3263
3446
 
@@ -3281,7 +3464,7 @@ export class Connection {
3281
3464
 
3282
3465
  const res = create(unsafeRes, GetFeeCalculatorRpcResult);
3283
3466
  if ('error' in res) {
3284
- throw new Error('failed to get fee calculator: ' + res.error.message);
3467
+ throw new SolanaJSONRPCError(res.error, 'failed to get fee calculator');
3285
3468
  }
3286
3469
  const {context, value} = res.result;
3287
3470
  return {
@@ -3303,7 +3486,7 @@ export class Connection {
3303
3486
 
3304
3487
  const res = create(unsafeRes, jsonRpcResultAndContext(nullable(number())));
3305
3488
  if ('error' in res) {
3306
- throw new Error('failed to get slot: ' + res.error.message);
3489
+ throw new SolanaJSONRPCError(res.error, 'failed to get slot');
3307
3490
  }
3308
3491
  if (res.result === null) {
3309
3492
  throw new Error('invalid blockhash');
@@ -3333,10 +3516,10 @@ export class Connection {
3333
3516
  * @return {Promise<BlockhashWithExpiryBlockHeight>}
3334
3517
  */
3335
3518
  async getLatestBlockhash(
3336
- commitment?: Commitment,
3519
+ commitmentOrConfig?: Commitment | GetLatestBlockhashConfig,
3337
3520
  ): Promise<BlockhashWithExpiryBlockHeight> {
3338
3521
  try {
3339
- const res = await this.getLatestBlockhashAndContext(commitment);
3522
+ const res = await this.getLatestBlockhashAndContext(commitmentOrConfig);
3340
3523
  return res.value;
3341
3524
  } catch (e) {
3342
3525
  throw new Error('failed to get recent blockhash: ' + e);
@@ -3348,13 +3531,20 @@ export class Connection {
3348
3531
  * @return {Promise<BlockhashWithExpiryBlockHeight>}
3349
3532
  */
3350
3533
  async getLatestBlockhashAndContext(
3351
- commitment?: Commitment,
3534
+ commitmentOrConfig?: Commitment | GetLatestBlockhashConfig,
3352
3535
  ): Promise<RpcResponseAndContext<BlockhashWithExpiryBlockHeight>> {
3353
- const args = this._buildArgs([], commitment);
3536
+ const {commitment, config} =
3537
+ extractCommitmentFromConfig(commitmentOrConfig);
3538
+ const args = this._buildArgs(
3539
+ [],
3540
+ commitment,
3541
+ undefined /* encoding */,
3542
+ config,
3543
+ );
3354
3544
  const unsafeRes = await this._rpcRequest('getLatestBlockhash', args);
3355
3545
  const res = create(unsafeRes, GetLatestBlockhashRpcResult);
3356
3546
  if ('error' in res) {
3357
- throw new Error('failed to get latest blockhash: ' + res.error.message);
3547
+ throw new SolanaJSONRPCError(res.error, 'failed to get latest blockhash');
3358
3548
  }
3359
3549
  return res.result;
3360
3550
  }
@@ -3366,7 +3556,7 @@ export class Connection {
3366
3556
  const unsafeRes = await this._rpcRequest('getVersion', []);
3367
3557
  const res = create(unsafeRes, jsonRpcResult(VersionResult));
3368
3558
  if ('error' in res) {
3369
- throw new Error('failed to get version: ' + res.error.message);
3559
+ throw new SolanaJSONRPCError(res.error, 'failed to get version');
3370
3560
  }
3371
3561
  return res.result;
3372
3562
  }
@@ -3378,7 +3568,7 @@ export class Connection {
3378
3568
  const unsafeRes = await this._rpcRequest('getGenesisHash', []);
3379
3569
  const res = create(unsafeRes, jsonRpcResult(string()));
3380
3570
  if ('error' in res) {
3381
- throw new Error('failed to get genesis hash: ' + res.error.message);
3571
+ throw new SolanaJSONRPCError(res.error, 'failed to get genesis hash');
3382
3572
  }
3383
3573
  return res.result;
3384
3574
  }
@@ -3398,7 +3588,7 @@ export class Connection {
3398
3588
  const res = create(unsafeRes, GetBlockRpcResult);
3399
3589
 
3400
3590
  if ('error' in res) {
3401
- throw new Error('failed to get confirmed block: ' + res.error.message);
3591
+ throw new SolanaJSONRPCError(res.error, 'failed to get confirmed block');
3402
3592
  }
3403
3593
 
3404
3594
  const result = res.result;
@@ -3422,13 +3612,23 @@ export class Connection {
3422
3612
  /*
3423
3613
  * Returns the current block height of the node
3424
3614
  */
3425
- async getBlockHeight(commitment?: Commitment): Promise<number> {
3426
- const args = this._buildArgs([], commitment);
3615
+ async getBlockHeight(
3616
+ commitmentOrConfig?: Commitment | GetBlockHeightConfig,
3617
+ ): Promise<number> {
3618
+ const {commitment, config} =
3619
+ extractCommitmentFromConfig(commitmentOrConfig);
3620
+ const args = this._buildArgs(
3621
+ [],
3622
+ commitment,
3623
+ undefined /* encoding */,
3624
+ config,
3625
+ );
3427
3626
  const unsafeRes = await this._rpcRequest('getBlockHeight', args);
3428
3627
  const res = create(unsafeRes, jsonRpcResult(number()));
3429
3628
  if ('error' in res) {
3430
- throw new Error(
3431
- 'failed to get block height information: ' + res.error.message,
3629
+ throw new SolanaJSONRPCError(
3630
+ res.error,
3631
+ 'failed to get block height information',
3432
3632
  );
3433
3633
  }
3434
3634
 
@@ -3456,8 +3656,9 @@ export class Connection {
3456
3656
  const unsafeRes = await this._rpcRequest('getBlockProduction', args);
3457
3657
  const res = create(unsafeRes, BlockProductionResponseStruct);
3458
3658
  if ('error' in res) {
3459
- throw new Error(
3460
- 'failed to get block production information: ' + res.error.message,
3659
+ throw new SolanaJSONRPCError(
3660
+ res.error,
3661
+ 'failed to get block production information',
3461
3662
  );
3462
3663
  }
3463
3664
 
@@ -3478,7 +3679,7 @@ export class Connection {
3478
3679
  const unsafeRes = await this._rpcRequest('getTransaction', args);
3479
3680
  const res = create(unsafeRes, GetTransactionRpcResult);
3480
3681
  if ('error' in res) {
3481
- throw new Error('failed to get transaction: ' + res.error.message);
3682
+ throw new SolanaJSONRPCError(res.error, 'failed to get transaction');
3482
3683
  }
3483
3684
 
3484
3685
  const result = res.result;
@@ -3508,7 +3709,7 @@ export class Connection {
3508
3709
  const unsafeRes = await this._rpcRequest('getTransaction', args);
3509
3710
  const res = create(unsafeRes, GetParsedTransactionRpcResult);
3510
3711
  if ('error' in res) {
3511
- throw new Error('failed to get transaction: ' + res.error.message);
3712
+ throw new SolanaJSONRPCError(res.error, 'failed to get transaction');
3512
3713
  }
3513
3714
  return res.result;
3514
3715
  }
@@ -3536,7 +3737,7 @@ export class Connection {
3536
3737
  const res = unsafeRes.map((unsafeRes: any) => {
3537
3738
  const res = create(unsafeRes, GetParsedTransactionRpcResult);
3538
3739
  if ('error' in res) {
3539
- throw new Error('failed to get transactions: ' + res.error.message);
3740
+ throw new SolanaJSONRPCError(res.error, 'failed to get transactions');
3540
3741
  }
3541
3742
  return res.result;
3542
3743
  });
@@ -3564,7 +3765,7 @@ export class Connection {
3564
3765
  const res = unsafeRes.map((unsafeRes: any) => {
3565
3766
  const res = create(unsafeRes, GetTransactionRpcResult);
3566
3767
  if ('error' in res) {
3567
- throw new Error('failed to get transactions: ' + res.error.message);
3768
+ throw new SolanaJSONRPCError(res.error, 'failed to get transactions');
3568
3769
  }
3569
3770
  const result = res.result;
3570
3771
  if (!result) return result;
@@ -3596,7 +3797,7 @@ export class Connection {
3596
3797
  const res = create(unsafeRes, GetConfirmedBlockRpcResult);
3597
3798
 
3598
3799
  if ('error' in res) {
3599
- throw new Error('failed to get confirmed block: ' + res.error.message);
3800
+ throw new SolanaJSONRPCError(res.error, 'failed to get confirmed block');
3600
3801
  }
3601
3802
 
3602
3803
  const result = res.result;
@@ -3647,7 +3848,7 @@ export class Connection {
3647
3848
  const unsafeRes = await this._rpcRequest('getBlocks', args);
3648
3849
  const res = create(unsafeRes, jsonRpcResult(array(number())));
3649
3850
  if ('error' in res) {
3650
- throw new Error('failed to get blocks: ' + res.error.message);
3851
+ throw new SolanaJSONRPCError(res.error, 'failed to get blocks');
3651
3852
  }
3652
3853
  return res.result;
3653
3854
  }
@@ -3671,7 +3872,7 @@ export class Connection {
3671
3872
  const unsafeRes = await this._rpcRequest('getBlock', args);
3672
3873
  const res = create(unsafeRes, GetBlockSignaturesRpcResult);
3673
3874
  if ('error' in res) {
3674
- throw new Error('failed to get block: ' + res.error.message);
3875
+ throw new SolanaJSONRPCError(res.error, 'failed to get block');
3675
3876
  }
3676
3877
  const result = res.result;
3677
3878
  if (!result) {
@@ -3701,7 +3902,7 @@ export class Connection {
3701
3902
  const unsafeRes = await this._rpcRequest('getConfirmedBlock', args);
3702
3903
  const res = create(unsafeRes, GetBlockSignaturesRpcResult);
3703
3904
  if ('error' in res) {
3704
- throw new Error('failed to get confirmed block: ' + res.error.message);
3905
+ throw new SolanaJSONRPCError(res.error, 'failed to get confirmed block');
3705
3906
  }
3706
3907
  const result = res.result;
3707
3908
  if (!result) {
@@ -3723,7 +3924,7 @@ export class Connection {
3723
3924
  const unsafeRes = await this._rpcRequest('getConfirmedTransaction', args);
3724
3925
  const res = create(unsafeRes, GetTransactionRpcResult);
3725
3926
  if ('error' in res) {
3726
- throw new Error('failed to get transaction: ' + res.error.message);
3927
+ throw new SolanaJSONRPCError(res.error, 'failed to get transaction');
3727
3928
  }
3728
3929
 
3729
3930
  const result = res.result;
@@ -3754,8 +3955,9 @@ export class Connection {
3754
3955
  const unsafeRes = await this._rpcRequest('getConfirmedTransaction', args);
3755
3956
  const res = create(unsafeRes, GetParsedTransactionRpcResult);
3756
3957
  if ('error' in res) {
3757
- throw new Error(
3758
- 'failed to get confirmed transaction: ' + res.error.message,
3958
+ throw new SolanaJSONRPCError(
3959
+ res.error,
3960
+ 'failed to get confirmed transaction',
3759
3961
  );
3760
3962
  }
3761
3963
  return res.result;
@@ -3786,8 +3988,9 @@ export class Connection {
3786
3988
  const res = unsafeRes.map((unsafeRes: any) => {
3787
3989
  const res = create(unsafeRes, GetParsedTransactionRpcResult);
3788
3990
  if ('error' in res) {
3789
- throw new Error(
3790
- 'failed to get confirmed transactions: ' + res.error.message,
3991
+ throw new SolanaJSONRPCError(
3992
+ res.error,
3993
+ 'failed to get confirmed transactions',
3791
3994
  );
3792
3995
  }
3793
3996
  return res.result;
@@ -3892,8 +4095,9 @@ export class Connection {
3892
4095
  );
3893
4096
  const res = create(unsafeRes, GetConfirmedSignaturesForAddress2RpcResult);
3894
4097
  if ('error' in res) {
3895
- throw new Error(
3896
- 'failed to get confirmed signatures for address: ' + res.error.message,
4098
+ throw new SolanaJSONRPCError(
4099
+ res.error,
4100
+ 'failed to get confirmed signatures for address',
3897
4101
  );
3898
4102
  }
3899
4103
  return res.result;
@@ -3921,8 +4125,9 @@ export class Connection {
3921
4125
  const unsafeRes = await this._rpcRequest('getSignaturesForAddress', args);
3922
4126
  const res = create(unsafeRes, GetSignaturesForAddressRpcResult);
3923
4127
  if ('error' in res) {
3924
- throw new Error(
3925
- 'failed to get signatures for address: ' + res.error.message,
4128
+ throw new SolanaJSONRPCError(
4129
+ res.error,
4130
+ 'failed to get signatures for address',
3926
4131
  );
3927
4132
  }
3928
4133
  return res.result;
@@ -3994,8 +4199,9 @@ export class Connection {
3994
4199
  ]);
3995
4200
  const res = create(unsafeRes, RequestAirdropRpcResult);
3996
4201
  if ('error' in res) {
3997
- throw new Error(
3998
- 'airdrop to ' + to.toBase58() + ' failed: ' + res.error.message,
4202
+ throw new SolanaJSONRPCError(
4203
+ res.error,
4204
+ `airdrop to ${to.toBase58()} failed`,
3999
4205
  );
4000
4206
  }
4001
4207
  return res.result;
@@ -4239,6 +4445,9 @@ export class Connection {
4239
4445
  if (options && options.maxRetries) {
4240
4446
  config.maxRetries = options.maxRetries;
4241
4447
  }
4448
+ if (options && options.minContextSlot != null) {
4449
+ config.minContextSlot = options.minContextSlot;
4450
+ }
4242
4451
  if (skipPreflight) {
4243
4452
  config.skipPreflight = skipPreflight;
4244
4453
  }