@solana/web3.js 1.66.5 → 1.67.1

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.66.5",
3
+ "version": "1.67.1",
4
4
  "description": "Solana Javascript API",
5
5
  "keywords": [
6
6
  "api",
@@ -79,7 +79,6 @@
79
79
  "@babel/plugin-transform-runtime": "^7.12.10",
80
80
  "@babel/preset-env": "^7.12.11",
81
81
  "@babel/preset-typescript": "^7.12.16",
82
- "@babel/register": "^7.12.13",
83
82
  "@commitlint/config-conventional": "^17.0.2",
84
83
  "@rollup/plugin-alias": "^3.1.9",
85
84
  "@rollup/plugin-babel": "^5.2.3",
@@ -112,7 +111,6 @@
112
111
  "eslint-plugin-mocha": "^10.1.0",
113
112
  "eslint-plugin-prettier": "^4.2.1",
114
113
  "esm": "^3.2.25",
115
- "http-server": "^14.0.0",
116
114
  "mocha": "^10.1.0",
117
115
  "mockttp": "^2.0.1",
118
116
  "mz": "^2.7.0",
package/src/account.ts CHANGED
@@ -23,7 +23,7 @@ export class Account {
23
23
  *
24
24
  * @param secretKey Secret key for the account
25
25
  */
26
- constructor(secretKey?: Buffer | Uint8Array | Array<number>) {
26
+ constructor(secretKey?: Uint8Array | Array<number>) {
27
27
  if (secretKey) {
28
28
  const secretKeyBuffer = toBuffer(secretKey);
29
29
  if (secretKey.length !== 64) {
package/src/connection.ts CHANGED
@@ -28,7 +28,7 @@ import {AgentManager} from './agent-manager';
28
28
  import {EpochSchedule} from './epoch-schedule';
29
29
  import {SendTransactionError, SolanaJSONRPCError} from './errors';
30
30
  import fetchImpl, {Response} from './fetch-impl';
31
- import {NonceAccount} from './nonce-account';
31
+ import {DurableNonce, NonceAccount} from './nonce-account';
32
32
  import {PublicKey} from './publickey';
33
33
  import {Signer} from './keypair';
34
34
  import {MS_PER_SLOT} from './timing';
@@ -45,6 +45,7 @@ import {sleep} from './utils/sleep';
45
45
  import {toBuffer} from './utils/to-buffer';
46
46
  import {
47
47
  TransactionExpiredBlockheightExceededError,
48
+ TransactionExpiredNonceInvalidError,
48
49
  TransactionExpiredTimeoutError,
49
50
  } from './transaction/expiry-custom-errors';
50
51
  import {makeWebsocketUrl} from './utils/makeWebsocketUrl';
@@ -338,6 +339,28 @@ function extractCommitmentFromConfig<TConfig>(
338
339
  return {commitment, config};
339
340
  }
340
341
 
342
+ /**
343
+ * A strategy for confirming durable nonce transactions.
344
+ */
345
+ export type DurableNonceTransactionConfirmationStrategy = {
346
+ /**
347
+ * The lowest slot at which to fetch the nonce value from the
348
+ * nonce account. This should be no lower than the slot at
349
+ * which the last-known value of the nonce was fetched.
350
+ */
351
+ minContextSlot: number;
352
+ /**
353
+ * The account where the current value of the nonce is stored.
354
+ */
355
+ nonceAccountPubkey: PublicKey;
356
+ /**
357
+ * The nonce value that was used to sign the transaction
358
+ * for which confirmation is being sought.
359
+ */
360
+ nonceValue: DurableNonce;
361
+ signature: TransactionSignature;
362
+ };
363
+
341
364
  /**
342
365
  * @internal
343
366
  */
@@ -2438,6 +2461,26 @@ export type GetTransactionCountConfig = {
2438
2461
  minContextSlot?: number;
2439
2462
  };
2440
2463
 
2464
+ /**
2465
+ * Configuration object for `getNonce`
2466
+ */
2467
+ export type GetNonceConfig = {
2468
+ /** Optional commitment level */
2469
+ commitment?: Commitment;
2470
+ /** The minimum slot that the request can be evaluated at */
2471
+ minContextSlot?: number;
2472
+ };
2473
+
2474
+ /**
2475
+ * Configuration object for `getNonceAndContext`
2476
+ */
2477
+ export type GetNonceAndContextConfig = {
2478
+ /** Optional commitment level */
2479
+ commitment?: Commitment;
2480
+ /** The minimum slot that the request can be evaluated at */
2481
+ minContextSlot?: number;
2482
+ };
2483
+
2441
2484
  /**
2442
2485
  * Information describing an account
2443
2486
  */
@@ -3348,7 +3391,9 @@ export class Connection {
3348
3391
  }
3349
3392
 
3350
3393
  confirmTransaction(
3351
- strategy: BlockheightBasedTransactionConfirmationStrategy,
3394
+ strategy:
3395
+ | BlockheightBasedTransactionConfirmationStrategy
3396
+ | DurableNonceTransactionConfirmationStrategy,
3352
3397
  commitment?: Commitment,
3353
3398
  ): Promise<RpcResponseAndContext<SignatureResult>>;
3354
3399
 
@@ -3363,6 +3408,7 @@ export class Connection {
3363
3408
  async confirmTransaction(
3364
3409
  strategy:
3365
3410
  | BlockheightBasedTransactionConfirmationStrategy
3411
+ | DurableNonceTransactionConfirmationStrategy
3366
3412
  | TransactionSignature,
3367
3413
  commitment?: Commitment,
3368
3414
  ): Promise<RpcResponseAndContext<SignatureResult>> {
@@ -3371,8 +3417,9 @@ export class Connection {
3371
3417
  if (typeof strategy == 'string') {
3372
3418
  rawSignature = strategy;
3373
3419
  } else {
3374
- const config =
3375
- strategy as BlockheightBasedTransactionConfirmationStrategy;
3420
+ const config = strategy as
3421
+ | BlockheightBasedTransactionConfirmationStrategy
3422
+ | DurableNonceTransactionConfirmationStrategy;
3376
3423
  rawSignature = config.signature;
3377
3424
  }
3378
3425
 
@@ -3386,31 +3433,58 @@ export class Connection {
3386
3433
 
3387
3434
  assert(decodedSignature.length === 64, 'signature has invalid length');
3388
3435
 
3389
- const confirmationCommitment = commitment || this.commitment;
3390
- let timeoutId;
3436
+ if (typeof strategy === 'string') {
3437
+ return await this.confirmTransactionUsingLegacyTimeoutStrategy({
3438
+ commitment: commitment || this.commitment,
3439
+ signature: rawSignature,
3440
+ });
3441
+ } else if ('lastValidBlockHeight' in strategy) {
3442
+ return await this.confirmTransactionUsingBlockHeightExceedanceStrategy({
3443
+ commitment: commitment || this.commitment,
3444
+ strategy,
3445
+ });
3446
+ } else {
3447
+ return await this.confirmTransactionUsingDurableNonceStrategy({
3448
+ commitment: commitment || this.commitment,
3449
+ strategy,
3450
+ });
3451
+ }
3452
+ }
3453
+
3454
+ private getTransactionConfirmationPromise({
3455
+ commitment,
3456
+ signature,
3457
+ }: {
3458
+ commitment?: Commitment;
3459
+ signature: string;
3460
+ }): {
3461
+ abortConfirmation(): void;
3462
+ confirmationPromise: Promise<{
3463
+ __type: TransactionStatus.PROCESSED;
3464
+ response: RpcResponseAndContext<SignatureResult>;
3465
+ }>;
3466
+ } {
3391
3467
  let signatureSubscriptionId: number | undefined;
3392
3468
  let disposeSignatureSubscriptionStateChangeObserver:
3393
3469
  | SubscriptionStateChangeDisposeFn
3394
3470
  | undefined;
3395
3471
  let done = false;
3396
-
3397
3472
  const confirmationPromise = new Promise<{
3398
3473
  __type: TransactionStatus.PROCESSED;
3399
3474
  response: RpcResponseAndContext<SignatureResult>;
3400
3475
  }>((resolve, reject) => {
3401
3476
  try {
3402
3477
  signatureSubscriptionId = this.onSignature(
3403
- rawSignature,
3478
+ signature,
3404
3479
  (result: SignatureResult, context: Context) => {
3405
3480
  signatureSubscriptionId = undefined;
3406
3481
  const response = {
3407
3482
  context,
3408
3483
  value: result,
3409
3484
  };
3410
- done = true;
3411
3485
  resolve({__type: TransactionStatus.PROCESSED, response});
3412
3486
  },
3413
- confirmationCommitment,
3487
+ commitment,
3414
3488
  );
3415
3489
  const subscriptionSetupPromise = new Promise<void>(
3416
3490
  resolveSubscriptionSetup => {
@@ -3432,7 +3506,7 @@ export class Connection {
3432
3506
  (async () => {
3433
3507
  await subscriptionSetupPromise;
3434
3508
  if (done) return;
3435
- const response = await this.getSignatureStatus(rawSignature);
3509
+ const response = await this.getSignatureStatus(signature);
3436
3510
  if (done) return;
3437
3511
  if (response == null) {
3438
3512
  return;
@@ -3444,7 +3518,7 @@ export class Connection {
3444
3518
  if (value?.err) {
3445
3519
  reject(value.err);
3446
3520
  } else {
3447
- switch (confirmationCommitment) {
3521
+ switch (commitment) {
3448
3522
  case 'confirmed':
3449
3523
  case 'single':
3450
3524
  case 'singleGossip': {
@@ -3482,80 +3556,250 @@ export class Connection {
3482
3556
  reject(err);
3483
3557
  }
3484
3558
  });
3559
+ const abortConfirmation = () => {
3560
+ if (disposeSignatureSubscriptionStateChangeObserver) {
3561
+ disposeSignatureSubscriptionStateChangeObserver();
3562
+ disposeSignatureSubscriptionStateChangeObserver = undefined;
3563
+ }
3564
+ if (signatureSubscriptionId) {
3565
+ this.removeSignatureListener(signatureSubscriptionId);
3566
+ signatureSubscriptionId = undefined;
3567
+ }
3568
+ };
3569
+ return {abortConfirmation, confirmationPromise};
3570
+ }
3485
3571
 
3486
- const expiryPromise = new Promise<
3487
- | {__type: TransactionStatus.BLOCKHEIGHT_EXCEEDED}
3488
- | {__type: TransactionStatus.TIMED_OUT; timeoutMs: number}
3489
- >(resolve => {
3490
- if (typeof strategy === 'string') {
3491
- let timeoutMs = this._confirmTransactionInitialTimeout || 60 * 1000;
3492
- switch (confirmationCommitment) {
3493
- case 'processed':
3494
- case 'recent':
3495
- case 'single':
3496
- case 'confirmed':
3497
- case 'singleGossip': {
3498
- timeoutMs = this._confirmTransactionInitialTimeout || 30 * 1000;
3499
- break;
3500
- }
3501
- // exhaust enums to ensure full coverage
3502
- case 'finalized':
3503
- case 'max':
3504
- case 'root':
3572
+ private async confirmTransactionUsingBlockHeightExceedanceStrategy({
3573
+ commitment,
3574
+ strategy: {lastValidBlockHeight, signature},
3575
+ }: {
3576
+ commitment?: Commitment;
3577
+ strategy: BlockheightBasedTransactionConfirmationStrategy;
3578
+ }) {
3579
+ let done: boolean = false;
3580
+ const expiryPromise = new Promise<{
3581
+ __type: TransactionStatus.BLOCKHEIGHT_EXCEEDED;
3582
+ }>(resolve => {
3583
+ const checkBlockHeight = async () => {
3584
+ try {
3585
+ const blockHeight = await this.getBlockHeight(commitment);
3586
+ return blockHeight;
3587
+ } catch (_e) {
3588
+ return -1;
3505
3589
  }
3506
-
3507
- timeoutId = setTimeout(
3508
- () => resolve({__type: TransactionStatus.TIMED_OUT, timeoutMs}),
3509
- timeoutMs,
3510
- );
3590
+ };
3591
+ (async () => {
3592
+ let currentBlockHeight = await checkBlockHeight();
3593
+ if (done) return;
3594
+ while (currentBlockHeight <= lastValidBlockHeight) {
3595
+ await sleep(1000);
3596
+ if (done) return;
3597
+ currentBlockHeight = await checkBlockHeight();
3598
+ if (done) return;
3599
+ }
3600
+ resolve({__type: TransactionStatus.BLOCKHEIGHT_EXCEEDED});
3601
+ })();
3602
+ });
3603
+ const {abortConfirmation, confirmationPromise} =
3604
+ this.getTransactionConfirmationPromise({commitment, signature});
3605
+ let result: RpcResponseAndContext<SignatureResult>;
3606
+ try {
3607
+ const outcome = await Promise.race([confirmationPromise, expiryPromise]);
3608
+ if (outcome.__type === TransactionStatus.PROCESSED) {
3609
+ result = outcome.response;
3511
3610
  } else {
3512
- let config =
3513
- strategy as BlockheightBasedTransactionConfirmationStrategy;
3514
- const checkBlockHeight = async () => {
3515
- try {
3516
- const blockHeight = await this.getBlockHeight(commitment);
3517
- return blockHeight;
3518
- } catch (_e) {
3519
- return -1;
3611
+ throw new TransactionExpiredBlockheightExceededError(signature);
3612
+ }
3613
+ } finally {
3614
+ done = true;
3615
+ abortConfirmation();
3616
+ }
3617
+ return result;
3618
+ }
3619
+
3620
+ private async confirmTransactionUsingDurableNonceStrategy({
3621
+ commitment,
3622
+ strategy: {minContextSlot, nonceAccountPubkey, nonceValue, signature},
3623
+ }: {
3624
+ commitment?: Commitment;
3625
+ strategy: DurableNonceTransactionConfirmationStrategy;
3626
+ }) {
3627
+ let done: boolean = false;
3628
+ const expiryPromise = new Promise<{
3629
+ __type: TransactionStatus.NONCE_INVALID;
3630
+ slotInWhichNonceDidAdvance: number | null;
3631
+ }>(resolve => {
3632
+ let currentNonceValue: string | undefined = nonceValue;
3633
+ let lastCheckedSlot: number | null = null;
3634
+ const getCurrentNonceValue = async () => {
3635
+ try {
3636
+ const {context, value: nonceAccount} = await this.getNonceAndContext(
3637
+ nonceAccountPubkey,
3638
+ {
3639
+ commitment,
3640
+ minContextSlot,
3641
+ },
3642
+ );
3643
+ lastCheckedSlot = context.slot;
3644
+ return nonceAccount?.nonce;
3645
+ } catch (e) {
3646
+ // If for whatever reason we can't reach/read the nonce
3647
+ // account, just keep using the last-known value.
3648
+ return currentNonceValue;
3649
+ }
3650
+ };
3651
+ (async () => {
3652
+ currentNonceValue = await getCurrentNonceValue();
3653
+ if (done) return;
3654
+ while (
3655
+ true // eslint-disable-line no-constant-condition
3656
+ ) {
3657
+ if (nonceValue !== currentNonceValue) {
3658
+ resolve({
3659
+ __type: TransactionStatus.NONCE_INVALID,
3660
+ slotInWhichNonceDidAdvance: lastCheckedSlot,
3661
+ });
3662
+ return;
3520
3663
  }
3521
- };
3522
- (async () => {
3523
- let currentBlockHeight = await checkBlockHeight();
3664
+ await sleep(2000);
3524
3665
  if (done) return;
3525
- while (currentBlockHeight <= config.lastValidBlockHeight) {
3526
- await sleep(1000);
3527
- if (done) return;
3528
- currentBlockHeight = await checkBlockHeight();
3529
- if (done) return;
3530
- }
3531
- resolve({__type: TransactionStatus.BLOCKHEIGHT_EXCEEDED});
3532
- })();
3533
- }
3666
+ currentNonceValue = await getCurrentNonceValue();
3667
+ if (done) return;
3668
+ }
3669
+ })();
3534
3670
  });
3535
-
3671
+ const {abortConfirmation, confirmationPromise} =
3672
+ this.getTransactionConfirmationPromise({commitment, signature});
3536
3673
  let result: RpcResponseAndContext<SignatureResult>;
3537
3674
  try {
3538
3675
  const outcome = await Promise.race([confirmationPromise, expiryPromise]);
3539
- switch (outcome.__type) {
3540
- case TransactionStatus.BLOCKHEIGHT_EXCEEDED:
3541
- throw new TransactionExpiredBlockheightExceededError(rawSignature);
3542
- case TransactionStatus.PROCESSED:
3543
- result = outcome.response;
3676
+ if (outcome.__type === TransactionStatus.PROCESSED) {
3677
+ result = outcome.response;
3678
+ } else {
3679
+ // Double check that the transaction is indeed unconfirmed.
3680
+ let signatureStatus:
3681
+ | RpcResponseAndContext<SignatureStatus | null>
3682
+ | null
3683
+ | undefined;
3684
+ while (
3685
+ true // eslint-disable-line no-constant-condition
3686
+ ) {
3687
+ const status = await this.getSignatureStatus(signature);
3688
+ if (status == null) {
3689
+ break;
3690
+ }
3691
+ if (
3692
+ status.context.slot <
3693
+ (outcome.slotInWhichNonceDidAdvance ?? minContextSlot)
3694
+ ) {
3695
+ await sleep(400);
3696
+ continue;
3697
+ }
3698
+ signatureStatus = status;
3544
3699
  break;
3545
- case TransactionStatus.TIMED_OUT:
3546
- throw new TransactionExpiredTimeoutError(
3547
- rawSignature,
3548
- outcome.timeoutMs / 1000,
3549
- );
3700
+ }
3701
+ if (signatureStatus?.value) {
3702
+ const commitmentForStatus = commitment || 'finalized';
3703
+ const {confirmationStatus} = signatureStatus.value;
3704
+ switch (commitmentForStatus) {
3705
+ case 'processed':
3706
+ case 'recent':
3707
+ if (
3708
+ confirmationStatus !== 'processed' &&
3709
+ confirmationStatus !== 'confirmed' &&
3710
+ confirmationStatus !== 'finalized'
3711
+ ) {
3712
+ throw new TransactionExpiredNonceInvalidError(signature);
3713
+ }
3714
+ break;
3715
+ case 'confirmed':
3716
+ case 'single':
3717
+ case 'singleGossip':
3718
+ if (
3719
+ confirmationStatus !== 'confirmed' &&
3720
+ confirmationStatus !== 'finalized'
3721
+ ) {
3722
+ throw new TransactionExpiredNonceInvalidError(signature);
3723
+ }
3724
+ break;
3725
+ case 'finalized':
3726
+ case 'max':
3727
+ case 'root':
3728
+ if (confirmationStatus !== 'finalized') {
3729
+ throw new TransactionExpiredNonceInvalidError(signature);
3730
+ }
3731
+ break;
3732
+ default:
3733
+ // Exhaustive switch.
3734
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3735
+ ((_: never) => {})(commitmentForStatus);
3736
+ }
3737
+ result = {
3738
+ context: signatureStatus.context,
3739
+ value: {err: signatureStatus.value.err},
3740
+ };
3741
+ } else {
3742
+ throw new TransactionExpiredNonceInvalidError(signature);
3743
+ }
3550
3744
  }
3551
3745
  } finally {
3552
- clearTimeout(timeoutId);
3553
- if (disposeSignatureSubscriptionStateChangeObserver) {
3554
- disposeSignatureSubscriptionStateChangeObserver();
3746
+ done = true;
3747
+ abortConfirmation();
3748
+ }
3749
+ return result;
3750
+ }
3751
+
3752
+ private async confirmTransactionUsingLegacyTimeoutStrategy({
3753
+ commitment,
3754
+ signature,
3755
+ }: {
3756
+ commitment?: Commitment;
3757
+ signature: string;
3758
+ }) {
3759
+ let timeoutId;
3760
+ const expiryPromise = new Promise<{
3761
+ __type: TransactionStatus.TIMED_OUT;
3762
+ timeoutMs: number;
3763
+ }>(resolve => {
3764
+ let timeoutMs = this._confirmTransactionInitialTimeout || 60 * 1000;
3765
+ switch (commitment) {
3766
+ case 'processed':
3767
+ case 'recent':
3768
+ case 'single':
3769
+ case 'confirmed':
3770
+ case 'singleGossip': {
3771
+ timeoutMs = this._confirmTransactionInitialTimeout || 30 * 1000;
3772
+ break;
3773
+ }
3774
+ // exhaust enums to ensure full coverage
3775
+ case 'finalized':
3776
+ case 'max':
3777
+ case 'root':
3555
3778
  }
3556
- if (signatureSubscriptionId) {
3557
- this.removeSignatureListener(signatureSubscriptionId);
3779
+ timeoutId = setTimeout(
3780
+ () => resolve({__type: TransactionStatus.TIMED_OUT, timeoutMs}),
3781
+ timeoutMs,
3782
+ );
3783
+ });
3784
+ const {abortConfirmation, confirmationPromise} =
3785
+ this.getTransactionConfirmationPromise({
3786
+ commitment,
3787
+ signature,
3788
+ });
3789
+ let result: RpcResponseAndContext<SignatureResult>;
3790
+ try {
3791
+ const outcome = await Promise.race([confirmationPromise, expiryPromise]);
3792
+ if (outcome.__type === TransactionStatus.PROCESSED) {
3793
+ result = outcome.response;
3794
+ } else {
3795
+ throw new TransactionExpiredTimeoutError(
3796
+ signature,
3797
+ outcome.timeoutMs / 1000,
3798
+ );
3558
3799
  }
3800
+ } finally {
3801
+ clearTimeout(timeoutId);
3802
+ abortConfirmation();
3559
3803
  }
3560
3804
  return result;
3561
3805
  }
@@ -4708,11 +4952,11 @@ export class Connection {
4708
4952
  */
4709
4953
  async getNonceAndContext(
4710
4954
  nonceAccount: PublicKey,
4711
- commitment?: Commitment,
4955
+ commitmentOrConfig?: Commitment | GetNonceAndContextConfig,
4712
4956
  ): Promise<RpcResponseAndContext<NonceAccount | null>> {
4713
4957
  const {context, value: accountInfo} = await this.getAccountInfoAndContext(
4714
4958
  nonceAccount,
4715
- commitment,
4959
+ commitmentOrConfig,
4716
4960
  );
4717
4961
 
4718
4962
  let value = null;
@@ -4731,9 +4975,9 @@ export class Connection {
4731
4975
  */
4732
4976
  async getNonce(
4733
4977
  nonceAccount: PublicKey,
4734
- commitment?: Commitment,
4978
+ commitmentOrConfig?: Commitment | GetNonceConfig,
4735
4979
  ): Promise<NonceAccount | null> {
4736
- return await this.getNonceAndContext(nonceAccount, commitment)
4980
+ return await this.getNonceAndContext(nonceAccount, commitmentOrConfig)
4737
4981
  .then(x => x.value)
4738
4982
  .catch(e => {
4739
4983
  throw new Error(
@@ -268,7 +268,7 @@ export class Message {
268
268
  // Slice up wire data
269
269
  let byteArray = [...buffer];
270
270
 
271
- const numRequiredSignatures = byteArray.shift() as number;
271
+ const numRequiredSignatures = byteArray.shift()!;
272
272
  if (
273
273
  numRequiredSignatures !==
274
274
  (numRequiredSignatures & VERSION_PREFIX_MASK)
@@ -278,8 +278,8 @@ export class Message {
278
278
  );
279
279
  }
280
280
 
281
- const numReadonlySignedAccounts = byteArray.shift() as number;
282
- const numReadonlyUnsignedAccounts = byteArray.shift() as number;
281
+ const numReadonlySignedAccounts = byteArray.shift()!;
282
+ const numReadonlyUnsignedAccounts = byteArray.shift()!;
283
283
 
284
284
  const accountCount = shortvec.decodeLength(byteArray);
285
285
  let accountKeys = [];
@@ -295,7 +295,7 @@ export class Message {
295
295
  const instructionCount = shortvec.decodeLength(byteArray);
296
296
  let instructions: CompiledInstruction[] = [];
297
297
  for (let i = 0; i < instructionCount; i++) {
298
- const programIdIndex = byteArray.shift() as number;
298
+ const programIdIndex = byteArray.shift()!;
299
299
  const accountCount = shortvec.decodeLength(byteArray);
300
300
  const accounts = byteArray.slice(0, accountCount);
301
301
  byteArray = byteArray.slice(accountCount);
@@ -1,7 +1,6 @@
1
1
  import * as BufferLayout from '@solana/buffer-layout';
2
2
  import {Buffer} from 'buffer';
3
3
 
4
- import type {Blockhash} from './blockhash';
5
4
  import * as Layout from './layout';
6
5
  import {PublicKey} from './publickey';
7
6
  import type {FeeCalculator} from './fee-calculator';
@@ -36,9 +35,14 @@ const NonceAccountLayout = BufferLayout.struct<
36
35
 
37
36
  export const NONCE_ACCOUNT_LENGTH = NonceAccountLayout.span;
38
37
 
38
+ /**
39
+ * A durable nonce is a 32 byte value encoded as a base58 string.
40
+ */
41
+ export type DurableNonce = string;
42
+
39
43
  type NonceAccountArgs = {
40
44
  authorizedPubkey: PublicKey;
41
- nonce: Blockhash;
45
+ nonce: DurableNonce;
42
46
  feeCalculator: FeeCalculator;
43
47
  };
44
48
 
@@ -47,7 +51,7 @@ type NonceAccountArgs = {
47
51
  */
48
52
  export class NonceAccount {
49
53
  authorizedPubkey: PublicKey;
50
- nonce: Blockhash;
54
+ nonce: DurableNonce;
51
55
  feeCalculator: FeeCalculator;
52
56
 
53
57
  /**
package/src/publickey.ts CHANGED
@@ -69,14 +69,14 @@ export class PublicKey extends Struct {
69
69
  this._bn = new BN(value);
70
70
  }
71
71
 
72
- if (this._bn.byteLength() > 32) {
72
+ if (this._bn.byteLength() > PUBLIC_KEY_LENGTH) {
73
73
  throw new Error(`Invalid public key input`);
74
74
  }
75
75
  }
76
76
  }
77
77
 
78
78
  /**
79
- * Returns a unique PublicKey for tests and benchmarks using acounter
79
+ * Returns a unique PublicKey for tests and benchmarks using a counter
80
80
  */
81
81
  static unique(): PublicKey {
82
82
  const key = new PublicKey(uniquePublicKeyCounter);
@@ -186,6 +186,8 @@ export class PublicKey extends Struct {
186
186
  /**
187
187
  * Async version of createProgramAddressSync
188
188
  * For backwards compatibility
189
+ *
190
+ * @deprecated Use {@link createProgramAddressSync} instead
189
191
  */
190
192
  /* eslint-disable require-await */
191
193
  static async createProgramAddress(
@@ -227,6 +229,8 @@ export class PublicKey extends Struct {
227
229
  /**
228
230
  * Async version of findProgramAddressSync
229
231
  * For backwards compatibility
232
+ *
233
+ * @deprecated Use {@link findProgramAddressSync} instead
230
234
  */
231
235
  static async findProgramAddress(
232
236
  seeds: Array<Buffer | Uint8Array>,
@@ -33,3 +33,16 @@ export class TransactionExpiredTimeoutError extends Error {
33
33
  Object.defineProperty(TransactionExpiredTimeoutError.prototype, 'name', {
34
34
  value: 'TransactionExpiredTimeoutError',
35
35
  });
36
+
37
+ export class TransactionExpiredNonceInvalidError extends Error {
38
+ signature: string;
39
+
40
+ constructor(signature: string) {
41
+ super(`Signature ${signature} has expired: the nonce is no longer valid.`);
42
+ this.signature = signature;
43
+ }
44
+ }
45
+
46
+ Object.defineProperty(TransactionExpiredNonceInvalidError.prototype, 'name', {
47
+ value: 'TransactionExpiredNonceInvalidError',
48
+ });