@solana/web3.js 1.32.0 → 1.34.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
@@ -99,6 +99,8 @@ export type SendOptions = {
99
99
  skipPreflight?: boolean;
100
100
  /** preflight commitment level */
101
101
  preflightCommitment?: Commitment;
102
+ /** Maximum number of times for the RPC node to retry sending the transaction to the leader. */
103
+ maxRetries?: number;
102
104
  };
103
105
 
104
106
  /**
@@ -111,6 +113,8 @@ export type ConfirmOptions = {
111
113
  commitment?: Commitment;
112
114
  /** preflight commitment level */
113
115
  preflightCommitment?: Commitment;
116
+ /** Maximum number of times for the RPC node to retry sending the transaction to the leader. */
117
+ maxRetries?: number;
114
118
  };
115
119
 
116
120
  /**
@@ -504,8 +508,15 @@ export type TokenBalance = {
504
508
 
505
509
  /**
506
510
  * Metadata for a parsed confirmed transaction on the ledger
511
+ *
512
+ * @deprecated Deprecated since Solana v1.8.0. Please use {@link ParsedTransactionMeta} instead.
507
513
  */
508
- export type ParsedConfirmedTransactionMeta = {
514
+ export type ParsedConfirmedTransactionMeta = ParsedTransactionMeta;
515
+
516
+ /**
517
+ * Metadata for a parsed transaction on the ledger
518
+ */
519
+ export type ParsedTransactionMeta = {
509
520
  /** The fee charged for processing the transaction */
510
521
  fee: number;
511
522
  /** An array of cross program invoked parsed instructions */
@@ -644,14 +655,21 @@ export type ParsedTransaction = {
644
655
 
645
656
  /**
646
657
  * A parsed and confirmed transaction on the ledger
658
+ *
659
+ * @deprecated Deprecated since Solana v1.8.0. Please use {@link ParsedTransactionWithMeta} instead.
660
+ */
661
+ export type ParsedConfirmedTransaction = ParsedTransactionWithMeta;
662
+
663
+ /**
664
+ * A parsed transaction on the ledger with meta
647
665
  */
648
- export type ParsedConfirmedTransaction = {
666
+ export type ParsedTransactionWithMeta = {
649
667
  /** The slot during which the transaction was processed */
650
668
  slot: number;
651
669
  /** The details of the transaction */
652
670
  transaction: ParsedTransaction;
653
671
  /** Metadata produced from the transaction */
654
- meta: ParsedConfirmedTransactionMeta | null;
672
+ meta: ParsedTransactionMeta | null;
655
673
  /** The unix timestamp of when the transaction was processed */
656
674
  blockTime?: number | null;
657
675
  };
@@ -720,9 +738,9 @@ export type ConfirmedBlock = {
720
738
  };
721
739
 
722
740
  /**
723
- * A ConfirmedBlock on the ledger with signatures only
741
+ * A Block on the ledger with signatures only
724
742
  */
725
- export type ConfirmedBlockSignatures = {
743
+ export type BlockSignatures = {
726
744
  /** Blockhash of this block */
727
745
  blockhash: Blockhash;
728
746
  /** Blockhash of this block's parent */
@@ -1494,8 +1512,41 @@ const ParsedConfirmedTransactionMetaResult = pick({
1494
1512
  postTokenBalances: optional(nullable(array(TokenBalanceResult))),
1495
1513
  });
1496
1514
 
1515
+ /**
1516
+ * Expected JSON RPC response for the "getBlock" message
1517
+ */
1518
+ const GetBlockRpcResult = jsonRpcResult(
1519
+ nullable(
1520
+ pick({
1521
+ blockhash: string(),
1522
+ previousBlockhash: string(),
1523
+ parentSlot: number(),
1524
+ transactions: array(
1525
+ pick({
1526
+ transaction: ConfirmedTransactionResult,
1527
+ meta: nullable(ConfirmedTransactionMetaResult),
1528
+ }),
1529
+ ),
1530
+ rewards: optional(
1531
+ array(
1532
+ pick({
1533
+ pubkey: string(),
1534
+ lamports: number(),
1535
+ postBalance: nullable(number()),
1536
+ rewardType: nullable(string()),
1537
+ }),
1538
+ ),
1539
+ ),
1540
+ blockTime: nullable(number()),
1541
+ blockHeight: nullable(number()),
1542
+ }),
1543
+ ),
1544
+ );
1545
+
1497
1546
  /**
1498
1547
  * Expected JSON RPC response for the "getConfirmedBlock" message
1548
+ *
1549
+ * @deprecated Deprecated since Solana v1.8.0. Please use {@link GetBlockRpcResult} instead.
1499
1550
  */
1500
1551
  const GetConfirmedBlockRpcResult = jsonRpcResult(
1501
1552
  nullable(
@@ -1525,9 +1576,9 @@ const GetConfirmedBlockRpcResult = jsonRpcResult(
1525
1576
  );
1526
1577
 
1527
1578
  /**
1528
- * Expected JSON RPC response for the "getConfirmedBlockSignatures" message
1579
+ * Expected JSON RPC response for the "getBlock" message
1529
1580
  */
1530
- const GetConfirmedBlockSignaturesRpcResult = jsonRpcResult(
1581
+ const GetBlockSignaturesRpcResult = jsonRpcResult(
1531
1582
  nullable(
1532
1583
  pick({
1533
1584
  blockhash: string(),
@@ -1540,9 +1591,9 @@ const GetConfirmedBlockSignaturesRpcResult = jsonRpcResult(
1540
1591
  );
1541
1592
 
1542
1593
  /**
1543
- * Expected JSON RPC response for the "getConfirmedTransaction" message
1594
+ * Expected JSON RPC response for the "getTransaction" message
1544
1595
  */
1545
- const GetConfirmedTransactionRpcResult = jsonRpcResult(
1596
+ const GetTransactionRpcResult = jsonRpcResult(
1546
1597
  nullable(
1547
1598
  pick({
1548
1599
  slot: number(),
@@ -1554,9 +1605,9 @@ const GetConfirmedTransactionRpcResult = jsonRpcResult(
1554
1605
  );
1555
1606
 
1556
1607
  /**
1557
- * Expected JSON RPC response for the "getConfirmedTransaction" message
1608
+ * Expected parsed JSON RPC response for the "getTransaction" message
1558
1609
  */
1559
- const GetParsedConfirmedTransactionRpcResult = jsonRpcResult(
1610
+ const GetParsedTransactionRpcResult = jsonRpcResult(
1560
1611
  nullable(
1561
1612
  pick({
1562
1613
  slot: number(),
@@ -1569,6 +1620,8 @@ const GetParsedConfirmedTransactionRpcResult = jsonRpcResult(
1569
1620
 
1570
1621
  /**
1571
1622
  * Expected JSON RPC response for the "getRecentBlockhash" message
1623
+ *
1624
+ * @deprecated Deprecated since Solana v1.8.0. Please use {@link GetLatestBlockhashRpcResult} instead.
1572
1625
  */
1573
1626
  const GetRecentBlockhashAndContextRpcResult = jsonRpcResultAndContext(
1574
1627
  pick({
@@ -1579,6 +1632,16 @@ const GetRecentBlockhashAndContextRpcResult = jsonRpcResultAndContext(
1579
1632
  }),
1580
1633
  );
1581
1634
 
1635
+ /**
1636
+ * Expected JSON RPC response for the "getLatestBlockhash" message
1637
+ */
1638
+ const GetLatestBlockhashRpcResult = jsonRpcResultAndContext(
1639
+ pick({
1640
+ blockhash: string(),
1641
+ lastValidBlockHeight: number(),
1642
+ }),
1643
+ );
1644
+
1582
1645
  const PerfSampleResult = pick({
1583
1646
  slot: number(),
1584
1647
  numTransactions: number(),
@@ -2962,6 +3025,8 @@ export class Connection {
2962
3025
  /**
2963
3026
  * Fetch a recent blockhash from the cluster, return with context
2964
3027
  * @return {Promise<RpcResponseAndContext<{blockhash: Blockhash, feeCalculator: FeeCalculator}>>}
3028
+ *
3029
+ * @deprecated Deprecated since Solana v1.8.0. Please use {@link getLatestBlockhash} instead.
2965
3030
  */
2966
3031
  async getRecentBlockhashAndContext(
2967
3032
  commitment?: Commitment,
@@ -3001,6 +3066,8 @@ export class Connection {
3001
3066
 
3002
3067
  /**
3003
3068
  * Fetch the fee calculator for a recent blockhash from the cluster, return with context
3069
+ *
3070
+ * @deprecated Deprecated since Solana v1.8.0. Please use {@link getFeeForMessage} instead.
3004
3071
  */
3005
3072
  async getFeeCalculatorForBlockhash(
3006
3073
  blockhash: Blockhash,
@@ -3047,6 +3114,8 @@ export class Connection {
3047
3114
  /**
3048
3115
  * Fetch a recent blockhash from the cluster
3049
3116
  * @return {Promise<{blockhash: Blockhash, feeCalculator: FeeCalculator}>}
3117
+ *
3118
+ * @deprecated Deprecated since Solana v1.8.0. Please use {@link getLatestBlockhash} instead.
3050
3119
  */
3051
3120
  async getRecentBlockhash(
3052
3121
  commitment?: Commitment,
@@ -3059,6 +3128,39 @@ export class Connection {
3059
3128
  }
3060
3129
  }
3061
3130
 
3131
+ /**
3132
+ * Fetch the latest blockhash from the cluster
3133
+ * @return {Promise<{blockhash: Blockhash, lastValidBlockHeight: number}>}
3134
+ */
3135
+ async getLatestBlockhash(
3136
+ commitment?: Commitment,
3137
+ ): Promise<{blockhash: Blockhash; lastValidBlockHeight: number}> {
3138
+ try {
3139
+ const res = await this.getLatestBlockhashAndContext(commitment);
3140
+ return res.value;
3141
+ } catch (e) {
3142
+ throw new Error('failed to get recent blockhash: ' + e);
3143
+ }
3144
+ }
3145
+
3146
+ /**
3147
+ * Fetch the latest blockhash from the cluster
3148
+ * @return {Promise<{blockhash: Blockhash, lastValidBlockHeight: number}>}
3149
+ */
3150
+ async getLatestBlockhashAndContext(
3151
+ commitment?: Commitment,
3152
+ ): Promise<
3153
+ RpcResponseAndContext<{blockhash: Blockhash; lastValidBlockHeight: number}>
3154
+ > {
3155
+ const args = this._buildArgs([], commitment);
3156
+ const unsafeRes = await this._rpcRequest('getLatestBlockhash', args);
3157
+ const res = create(unsafeRes, GetLatestBlockhashRpcResult);
3158
+ if ('error' in res) {
3159
+ throw new Error('failed to get latest blockhash: ' + res.error.message);
3160
+ }
3161
+ return res.result;
3162
+ }
3163
+
3062
3164
  /**
3063
3165
  * Fetch the node version
3064
3166
  */
@@ -3094,8 +3196,8 @@ export class Connection {
3094
3196
  [slot],
3095
3197
  opts && opts.commitment,
3096
3198
  );
3097
- const unsafeRes = await this._rpcRequest('getConfirmedBlock', args);
3098
- const res = create(unsafeRes, GetConfirmedBlockRpcResult);
3199
+ const unsafeRes = await this._rpcRequest('getBlock', args);
3200
+ const res = create(unsafeRes, GetBlockRpcResult);
3099
3201
 
3100
3202
  if ('error' in res) {
3101
3203
  throw new Error('failed to get confirmed block: ' + res.error.message);
@@ -3120,7 +3222,7 @@ export class Connection {
3120
3222
  }
3121
3223
 
3122
3224
  /**
3123
- * Fetch a processed transaction from the cluster.
3225
+ * Fetch a confirmed or finalized transaction from the cluster.
3124
3226
  */
3125
3227
  async getTransaction(
3126
3228
  signature: string,
@@ -3130,12 +3232,10 @@ export class Connection {
3130
3232
  [signature],
3131
3233
  opts && opts.commitment,
3132
3234
  );
3133
- const unsafeRes = await this._rpcRequest('getConfirmedTransaction', args);
3134
- const res = create(unsafeRes, GetConfirmedTransactionRpcResult);
3235
+ const unsafeRes = await this._rpcRequest('getTransaction', args);
3236
+ const res = create(unsafeRes, GetTransactionRpcResult);
3135
3237
  if ('error' in res) {
3136
- throw new Error(
3137
- 'failed to get confirmed transaction: ' + res.error.message,
3138
- );
3238
+ throw new Error('failed to get transaction: ' + res.error.message);
3139
3239
  }
3140
3240
 
3141
3241
  const result = res.result;
@@ -3150,6 +3250,57 @@ export class Connection {
3150
3250
  };
3151
3251
  }
3152
3252
 
3253
+ /**
3254
+ * Fetch parsed transaction details for a confirmed or finalized transaction
3255
+ */
3256
+ async getParsedTransaction(
3257
+ signature: TransactionSignature,
3258
+ commitment?: Finality,
3259
+ ): Promise<ParsedConfirmedTransaction | null> {
3260
+ const args = this._buildArgsAtLeastConfirmed(
3261
+ [signature],
3262
+ commitment,
3263
+ 'jsonParsed',
3264
+ );
3265
+ const unsafeRes = await this._rpcRequest('getTransaction', args);
3266
+ const res = create(unsafeRes, GetParsedTransactionRpcResult);
3267
+ if ('error' in res) {
3268
+ throw new Error('failed to get transaction: ' + res.error.message);
3269
+ }
3270
+ return res.result;
3271
+ }
3272
+
3273
+ /**
3274
+ * Fetch parsed transaction details for a batch of confirmed transactions
3275
+ */
3276
+ async getParsedTransactions(
3277
+ signatures: TransactionSignature[],
3278
+ commitment?: Finality,
3279
+ ): Promise<(ParsedConfirmedTransaction | null)[]> {
3280
+ const batch = signatures.map(signature => {
3281
+ const args = this._buildArgsAtLeastConfirmed(
3282
+ [signature],
3283
+ commitment,
3284
+ 'jsonParsed',
3285
+ );
3286
+ return {
3287
+ methodName: 'getTransaction',
3288
+ args,
3289
+ };
3290
+ });
3291
+
3292
+ const unsafeRes = await this._rpcBatchRequest(batch);
3293
+ const res = unsafeRes.map((unsafeRes: any) => {
3294
+ const res = create(unsafeRes, GetParsedTransactionRpcResult);
3295
+ if ('error' in res) {
3296
+ throw new Error('failed to get transactions: ' + res.error.message);
3297
+ }
3298
+ return res.result;
3299
+ });
3300
+
3301
+ return res;
3302
+ }
3303
+
3153
3304
  /**
3154
3305
  * Fetch a list of Transactions and transaction statuses from the cluster
3155
3306
  * for a confirmed block.
@@ -3160,14 +3311,36 @@ export class Connection {
3160
3311
  slot: number,
3161
3312
  commitment?: Finality,
3162
3313
  ): Promise<ConfirmedBlock> {
3163
- const result = await this.getBlock(slot, {commitment});
3314
+ const args = this._buildArgsAtLeastConfirmed([slot], commitment);
3315
+ const unsafeRes = await this._rpcRequest('getConfirmedBlock', args);
3316
+ const res = create(unsafeRes, GetConfirmedBlockRpcResult);
3317
+
3318
+ if ('error' in res) {
3319
+ throw new Error('failed to get confirmed block: ' + res.error.message);
3320
+ }
3321
+
3322
+ const result = res.result;
3164
3323
  if (!result) {
3165
3324
  throw new Error('Confirmed block ' + slot + ' not found');
3166
3325
  }
3167
3326
 
3168
- return {
3327
+ const block = {
3169
3328
  ...result,
3170
3329
  transactions: result.transactions.map(({transaction, meta}) => {
3330
+ const message = new Message(transaction.message);
3331
+ return {
3332
+ meta,
3333
+ transaction: {
3334
+ ...transaction,
3335
+ message,
3336
+ },
3337
+ };
3338
+ }),
3339
+ };
3340
+
3341
+ return {
3342
+ ...block,
3343
+ transactions: block.transactions.map(({transaction, meta}) => {
3171
3344
  return {
3172
3345
  meta,
3173
3346
  transaction: Transaction.populate(
@@ -3191,7 +3364,7 @@ export class Connection {
3191
3364
  endSlot !== undefined ? [startSlot, endSlot] : [startSlot],
3192
3365
  commitment,
3193
3366
  );
3194
- const unsafeRes = await this._rpcRequest('getConfirmedBlocks', args);
3367
+ const unsafeRes = await this._rpcRequest('getBlocks', args);
3195
3368
  const res = create(unsafeRes, jsonRpcResult(array(number())));
3196
3369
  if ('error' in res) {
3197
3370
  throw new Error('failed to get blocks: ' + res.error.message);
@@ -3199,13 +3372,43 @@ export class Connection {
3199
3372
  return res.result;
3200
3373
  }
3201
3374
 
3375
+ /**
3376
+ * Fetch a list of Signatures from the cluster for a block, excluding rewards
3377
+ */
3378
+ async getBlockSignatures(
3379
+ slot: number,
3380
+ commitment?: Finality,
3381
+ ): Promise<BlockSignatures> {
3382
+ const args = this._buildArgsAtLeastConfirmed(
3383
+ [slot],
3384
+ commitment,
3385
+ undefined,
3386
+ {
3387
+ transactionDetails: 'signatures',
3388
+ rewards: false,
3389
+ },
3390
+ );
3391
+ const unsafeRes = await this._rpcRequest('getBlock', args);
3392
+ const res = create(unsafeRes, GetBlockSignaturesRpcResult);
3393
+ if ('error' in res) {
3394
+ throw new Error('failed to get block: ' + res.error.message);
3395
+ }
3396
+ const result = res.result;
3397
+ if (!result) {
3398
+ throw new Error('Block ' + slot + ' not found');
3399
+ }
3400
+ return result;
3401
+ }
3402
+
3202
3403
  /**
3203
3404
  * Fetch a list of Signatures from the cluster for a confirmed block, excluding rewards
3405
+ *
3406
+ * @deprecated Deprecated since Solana v1.8.0. Please use {@link getBlockSignatures} instead.
3204
3407
  */
3205
3408
  async getConfirmedBlockSignatures(
3206
3409
  slot: number,
3207
3410
  commitment?: Finality,
3208
- ): Promise<ConfirmedBlockSignatures> {
3411
+ ): Promise<BlockSignatures> {
3209
3412
  const args = this._buildArgsAtLeastConfirmed(
3210
3413
  [slot],
3211
3414
  commitment,
@@ -3216,7 +3419,7 @@ export class Connection {
3216
3419
  },
3217
3420
  );
3218
3421
  const unsafeRes = await this._rpcRequest('getConfirmedBlock', args);
3219
- const res = create(unsafeRes, GetConfirmedBlockSignaturesRpcResult);
3422
+ const res = create(unsafeRes, GetBlockSignaturesRpcResult);
3220
3423
  if ('error' in res) {
3221
3424
  throw new Error('failed to get confirmed block: ' + res.error.message);
3222
3425
  }
@@ -3229,14 +3432,25 @@ export class Connection {
3229
3432
 
3230
3433
  /**
3231
3434
  * Fetch a transaction details for a confirmed transaction
3435
+ *
3436
+ * @deprecated Deprecated since Solana v1.8.0. Please use {@link getTransaction} instead.
3232
3437
  */
3233
3438
  async getConfirmedTransaction(
3234
3439
  signature: TransactionSignature,
3235
3440
  commitment?: Finality,
3236
3441
  ): Promise<ConfirmedTransaction | null> {
3237
- const result = await this.getTransaction(signature, {commitment});
3442
+ const args = this._buildArgsAtLeastConfirmed([signature], commitment);
3443
+ const unsafeRes = await this._rpcRequest('getConfirmedTransaction', args);
3444
+ const res = create(unsafeRes, GetTransactionRpcResult);
3445
+ if ('error' in res) {
3446
+ throw new Error('failed to get transaction: ' + res.error.message);
3447
+ }
3448
+
3449
+ const result = res.result;
3238
3450
  if (!result) return result;
3239
- const {message, signatures} = result.transaction;
3451
+
3452
+ const message = new Message(result.transaction.message);
3453
+ const signatures = result.transaction.signatures;
3240
3454
  return {
3241
3455
  ...result,
3242
3456
  transaction: Transaction.populate(message, signatures),
@@ -3245,6 +3459,8 @@ export class Connection {
3245
3459
 
3246
3460
  /**
3247
3461
  * Fetch parsed transaction details for a confirmed transaction
3462
+ *
3463
+ * @deprecated Deprecated since Solana v1.8.0. Please use {@link getParsedTransaction} instead.
3248
3464
  */
3249
3465
  async getParsedConfirmedTransaction(
3250
3466
  signature: TransactionSignature,
@@ -3256,7 +3472,7 @@ export class Connection {
3256
3472
  'jsonParsed',
3257
3473
  );
3258
3474
  const unsafeRes = await this._rpcRequest('getConfirmedTransaction', args);
3259
- const res = create(unsafeRes, GetParsedConfirmedTransactionRpcResult);
3475
+ const res = create(unsafeRes, GetParsedTransactionRpcResult);
3260
3476
  if ('error' in res) {
3261
3477
  throw new Error(
3262
3478
  'failed to get confirmed transaction: ' + res.error.message,
@@ -3267,6 +3483,8 @@ export class Connection {
3267
3483
 
3268
3484
  /**
3269
3485
  * Fetch parsed transaction details for a batch of confirmed transactions
3486
+ *
3487
+ * @deprecated Deprecated since Solana v1.8.0. Please use {@link getParsedTransactions} instead.
3270
3488
  */
3271
3489
  async getParsedConfirmedTransactions(
3272
3490
  signatures: TransactionSignature[],
@@ -3286,7 +3504,7 @@ export class Connection {
3286
3504
 
3287
3505
  const unsafeRes = await this._rpcBatchRequest(batch);
3288
3506
  const res = unsafeRes.map((unsafeRes: any) => {
3289
- const res = create(unsafeRes, GetParsedConfirmedTransactionRpcResult);
3507
+ const res = create(unsafeRes, GetParsedTransactionRpcResult);
3290
3508
  if ('error' in res) {
3291
3509
  throw new Error(
3292
3510
  'failed to get confirmed transactions: ' + res.error.message,
@@ -3717,6 +3935,9 @@ export class Connection {
3717
3935
  const preflightCommitment =
3718
3936
  (options && options.preflightCommitment) || this.commitment;
3719
3937
 
3938
+ if (options && options.maxRetries) {
3939
+ config.maxRetries = options.maxRetries;
3940
+ }
3720
3941
  if (skipPreflight) {
3721
3942
  config.skipPreflight = skipPreflight;
3722
3943
  }
@@ -3889,7 +4110,16 @@ export class Connection {
3889
4110
  this._rpcWebSocketConnected = false;
3890
4111
  this._rpcWebSocketIdleTimeout = setTimeout(() => {
3891
4112
  this._rpcWebSocketIdleTimeout = null;
3892
- this._rpcWebSocket.close();
4113
+ try {
4114
+ this._rpcWebSocket.close();
4115
+ } catch (err) {
4116
+ // swallow error if socket has already been closed.
4117
+ if (err instanceof Error) {
4118
+ console.log(
4119
+ `Error when closing socket connection: ${err.message}`,
4120
+ );
4121
+ }
4122
+ }
3893
4123
  }, 500);
3894
4124
  }
3895
4125
  return;
package/src/index.ts CHANGED
@@ -17,6 +17,7 @@ export * from './secp256k1-program';
17
17
  export * from './transaction';
18
18
  export * from './validator-info';
19
19
  export * from './vote-account';
20
+ export * from './vote-program';
20
21
  export * from './sysvar';
21
22
  export * from './errors';
22
23
  export * from './util/borsh-schema';
package/src/layout.ts CHANGED
@@ -79,6 +79,21 @@ export const lockup = (property: string = 'lockup') => {
79
79
  );
80
80
  };
81
81
 
82
+ /**
83
+ * Layout for a VoteInit object
84
+ */
85
+ export const voteInit = (property: string = 'voteInit') => {
86
+ return BufferLayout.struct(
87
+ [
88
+ publicKey('nodePubkey'),
89
+ publicKey('authorizedVoter'),
90
+ publicKey('authorizedWithdrawer'),
91
+ BufferLayout.u8('commission'),
92
+ ],
93
+ property,
94
+ );
95
+ };
96
+
82
97
  export function getAlloc(type: any, fields: any): number {
83
98
  let alloc = 0;
84
99
  type.layout.fields.forEach((item: any) => {
@@ -2,12 +2,12 @@ const endpoint = {
2
2
  http: {
3
3
  devnet: 'http://api.devnet.solana.com',
4
4
  testnet: 'http://api.testnet.solana.com',
5
- 'mainnet-beta': 'http://api.mainnet-beta.solana.com',
5
+ 'mainnet-beta': 'http://api.mainnet-beta.solana.com/',
6
6
  },
7
7
  https: {
8
8
  devnet: 'https://api.devnet.solana.com',
9
9
  testnet: 'https://api.testnet.solana.com',
10
- 'mainnet-beta': 'https://api.mainnet-beta.solana.com',
10
+ 'mainnet-beta': 'https://api.mainnet-beta.solana.com/',
11
11
  },
12
12
  };
13
13
 
@@ -24,6 +24,7 @@ export async function sendAndConfirmTransaction(
24
24
  const sendOptions = options && {
25
25
  skipPreflight: options.skipPreflight,
26
26
  preflightCommitment: options.preflightCommitment || options.commitment,
27
+ maxRetries: options.maxRetries,
27
28
  };
28
29
 
29
30
  const signature = await connection.sendTransaction(