@solana/web3.js 1.35.0 → 1.37.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/loader.ts CHANGED
@@ -9,6 +9,7 @@ import {sleep} from './util/sleep';
9
9
  import type {Connection} from './connection';
10
10
  import type {Signer} from './keypair';
11
11
  import {SystemProgram} from './system-program';
12
+ import {IInstructionInputData} from './instruction';
12
13
 
13
14
  // Keep program chunks under PACKET_DATA_SIZE, leaving enough room for the
14
15
  // rest of the Transaction fields
@@ -137,7 +138,15 @@ export class Loader {
137
138
  }
138
139
  }
139
140
 
140
- const dataLayout = BufferLayout.struct([
141
+ const dataLayout = BufferLayout.struct<
142
+ Readonly<{
143
+ bytes: number[];
144
+ bytesLength: number;
145
+ bytesLengthPadding: number;
146
+ instruction: number;
147
+ offset: number;
148
+ }>
149
+ >([
141
150
  BufferLayout.u32('instruction'),
142
151
  BufferLayout.u32('offset'),
143
152
  BufferLayout.u32('bytesLength'),
@@ -160,7 +169,9 @@ export class Loader {
160
169
  {
161
170
  instruction: 0, // Load instruction
162
171
  offset,
163
- bytes,
172
+ bytes: bytes as number[],
173
+ bytesLength: 0,
174
+ bytesLengthPadding: 0,
164
175
  },
165
176
  data,
166
177
  );
@@ -189,7 +200,9 @@ export class Loader {
189
200
 
190
201
  // Finalize the account loaded with program data for execution
191
202
  {
192
- const dataLayout = BufferLayout.struct([BufferLayout.u32('instruction')]);
203
+ const dataLayout = BufferLayout.struct<IInstructionInputData>([
204
+ BufferLayout.u32('instruction'),
205
+ ]);
193
206
 
194
207
  const data = Buffer.alloc(dataLayout.span);
195
208
  dataLayout.encode(
package/src/message.ts CHANGED
@@ -118,7 +118,7 @@ export class Message {
118
118
 
119
119
  const instructions = this.instructions.map(instruction => {
120
120
  const {accounts, programIdIndex} = instruction;
121
- const data = bs58.decode(instruction.data);
121
+ const data = Array.from(bs58.decode(instruction.data));
122
122
 
123
123
  let keyIndicesCount: number[] = [];
124
124
  shortvec.encodeLength(keyIndicesCount, accounts.length);
@@ -129,7 +129,7 @@ export class Message {
129
129
  return {
130
130
  programIdIndex,
131
131
  keyIndicesCount: Buffer.from(keyIndicesCount),
132
- keyIndices: Buffer.from(accounts),
132
+ keyIndices: accounts,
133
133
  dataLength: Buffer.from(dataCount),
134
134
  data,
135
135
  };
@@ -142,7 +142,15 @@ export class Message {
142
142
  let instructionBufferLength = instructionCount.length;
143
143
 
144
144
  instructions.forEach(instruction => {
145
- const instructionLayout = BufferLayout.struct([
145
+ const instructionLayout = BufferLayout.struct<
146
+ Readonly<{
147
+ data: number[];
148
+ dataLength: Uint8Array;
149
+ keyIndices: number[];
150
+ keyIndicesCount: Uint8Array;
151
+ programIdIndex: number;
152
+ }>
153
+ >([
146
154
  BufferLayout.u8('programIdIndex'),
147
155
 
148
156
  BufferLayout.blob(
@@ -170,7 +178,16 @@ export class Message {
170
178
  });
171
179
  instructionBuffer = instructionBuffer.slice(0, instructionBufferLength);
172
180
 
173
- const signDataLayout = BufferLayout.struct([
181
+ const signDataLayout = BufferLayout.struct<
182
+ Readonly<{
183
+ keyCount: Uint8Array;
184
+ keys: Uint8Array[];
185
+ numReadonlySignedAccounts: Uint8Array;
186
+ numReadonlyUnsignedAccounts: Uint8Array;
187
+ numRequiredSignatures: Uint8Array;
188
+ recentBlockhash: Uint8Array;
189
+ }>
190
+ >([
174
191
  BufferLayout.blob(1, 'numRequiredSignatures'),
175
192
  BufferLayout.blob(1, 'numReadonlySignedAccounts'),
176
193
  BufferLayout.blob(1, 'numReadonlyUnsignedAccounts'),
@@ -13,12 +13,25 @@ import {toBuffer} from './util/to-buffer';
13
13
  *
14
14
  * @internal
15
15
  */
16
- const NonceAccountLayout = BufferLayout.struct([
16
+ const NonceAccountLayout = BufferLayout.struct<
17
+ Readonly<{
18
+ authorizedPubkey: Uint8Array;
19
+ feeCalculator: Readonly<{
20
+ lamportsPerSignature: number;
21
+ }>;
22
+ nonce: Uint8Array;
23
+ state: number;
24
+ version: number;
25
+ }>
26
+ >([
17
27
  BufferLayout.u32('version'),
18
28
  BufferLayout.u32('state'),
19
29
  Layout.publicKey('authorizedPubkey'),
20
30
  Layout.publicKey('nonce'),
21
- BufferLayout.struct([FeeCalculatorLayout], 'feeCalculator'),
31
+ BufferLayout.struct<Readonly<{lamportsPerSignature: number}>>(
32
+ [FeeCalculatorLayout],
33
+ 'feeCalculator',
34
+ ),
22
35
  ]);
23
36
 
24
37
  export const NONCE_ACCOUNT_LENGTH = NonceAccountLayout.span;
@@ -46,7 +46,21 @@ export type CreateSecp256k1InstructionWithPrivateKeyParams = {
46
46
  instructionIndex?: number;
47
47
  };
48
48
 
49
- const SECP256K1_INSTRUCTION_LAYOUT = BufferLayout.struct([
49
+ const SECP256K1_INSTRUCTION_LAYOUT = BufferLayout.struct<
50
+ Readonly<{
51
+ ethAddress: Uint8Array;
52
+ ethAddressInstructionIndex: number;
53
+ ethAddressOffset: number;
54
+ messageDataOffset: number;
55
+ messageDataSize: number;
56
+ messageInstructionIndex: number;
57
+ numSignatures: number;
58
+ recoveryId: number;
59
+ signature: Uint8Array;
60
+ signatureInstructionIndex: number;
61
+ signatureOffset: number;
62
+ }>
63
+ >([
50
64
  BufferLayout.u8('numSignatures'),
51
65
  BufferLayout.u16('signatureOffset'),
52
66
  BufferLayout.u8('signatureInstructionIndex'),
@@ -1,6 +1,11 @@
1
1
  import * as BufferLayout from '@solana/buffer-layout';
2
2
 
3
- import {encodeData, decodeData, InstructionType} from './instruction';
3
+ import {
4
+ encodeData,
5
+ decodeData,
6
+ InstructionType,
7
+ IInstructionInputData,
8
+ } from './instruction';
4
9
  import * as Layout from './layout';
5
10
  import {PublicKey} from './publickey';
6
11
  import {SystemProgram} from './system-program';
@@ -40,6 +45,11 @@ export class Authorized {
40
45
  }
41
46
  }
42
47
 
48
+ type AuthorizedRaw = Readonly<{
49
+ staker: Uint8Array;
50
+ withdrawer: Uint8Array;
51
+ }>;
52
+
43
53
  /**
44
54
  * Stake account lockup info
45
55
  */
@@ -66,6 +76,12 @@ export class Lockup {
66
76
  static default: Lockup = new Lockup(0, 0, PublicKey.default);
67
77
  }
68
78
 
79
+ type LockupRaw = Readonly<{
80
+ custodian: Uint8Array;
81
+ epoch: number;
82
+ unixTimestamp: number;
83
+ }>;
84
+
69
85
  /**
70
86
  * Create stake account transaction params
71
87
  */
@@ -429,25 +445,63 @@ export class StakeInstruction {
429
445
  * An enumeration of valid StakeInstructionType's
430
446
  */
431
447
  export type StakeInstructionType =
432
- | 'AuthorizeWithSeed'
448
+ // FIXME
449
+ // It would be preferable for this type to be `keyof StakeInstructionInputData`
450
+ // but Typedoc does not transpile `keyof` expressions.
451
+ // See https://github.com/TypeStrong/typedoc/issues/1894
433
452
  | 'Authorize'
453
+ | 'AuthorizeWithSeed'
434
454
  | 'Deactivate'
435
455
  | 'Delegate'
436
456
  | 'Initialize'
457
+ | 'Merge'
437
458
  | 'Split'
438
- | 'Withdraw'
439
- | 'Merge';
459
+ | 'Withdraw';
460
+
461
+ type StakeInstructionInputData = {
462
+ Authorize: IInstructionInputData &
463
+ Readonly<{
464
+ newAuthorized: Uint8Array;
465
+ stakeAuthorizationType: number;
466
+ }>;
467
+ AuthorizeWithSeed: IInstructionInputData &
468
+ Readonly<{
469
+ authorityOwner: Uint8Array;
470
+ authoritySeed: string;
471
+ instruction: number;
472
+ newAuthorized: Uint8Array;
473
+ stakeAuthorizationType: number;
474
+ }>;
475
+ Deactivate: IInstructionInputData;
476
+ Delegate: IInstructionInputData;
477
+ Initialize: IInstructionInputData &
478
+ Readonly<{
479
+ authorized: AuthorizedRaw;
480
+ lockup: LockupRaw;
481
+ }>;
482
+ Merge: IInstructionInputData;
483
+ Split: IInstructionInputData &
484
+ Readonly<{
485
+ lamports: number;
486
+ }>;
487
+ Withdraw: IInstructionInputData &
488
+ Readonly<{
489
+ lamports: number;
490
+ }>;
491
+ };
440
492
 
441
493
  /**
442
494
  * An enumeration of valid stake InstructionType's
443
495
  * @internal
444
496
  */
445
- export const STAKE_INSTRUCTION_LAYOUTS: {
446
- [type in StakeInstructionType]: InstructionType;
447
- } = Object.freeze({
497
+ export const STAKE_INSTRUCTION_LAYOUTS = Object.freeze<{
498
+ [Instruction in StakeInstructionType]: InstructionType<
499
+ StakeInstructionInputData[Instruction]
500
+ >;
501
+ }>({
448
502
  Initialize: {
449
503
  index: 0,
450
- layout: BufferLayout.struct([
504
+ layout: BufferLayout.struct<StakeInstructionInputData['Initialize']>([
451
505
  BufferLayout.u32('instruction'),
452
506
  Layout.authorized(),
453
507
  Layout.lockup(),
@@ -455,7 +509,7 @@ export const STAKE_INSTRUCTION_LAYOUTS: {
455
509
  },
456
510
  Authorize: {
457
511
  index: 1,
458
- layout: BufferLayout.struct([
512
+ layout: BufferLayout.struct<StakeInstructionInputData['Authorize']>([
459
513
  BufferLayout.u32('instruction'),
460
514
  Layout.publicKey('newAuthorized'),
461
515
  BufferLayout.u32('stakeAuthorizationType'),
@@ -463,39 +517,47 @@ export const STAKE_INSTRUCTION_LAYOUTS: {
463
517
  },
464
518
  Delegate: {
465
519
  index: 2,
466
- layout: BufferLayout.struct([BufferLayout.u32('instruction')]),
520
+ layout: BufferLayout.struct<StakeInstructionInputData['Delegate']>([
521
+ BufferLayout.u32('instruction'),
522
+ ]),
467
523
  },
468
524
  Split: {
469
525
  index: 3,
470
- layout: BufferLayout.struct([
526
+ layout: BufferLayout.struct<StakeInstructionInputData['Split']>([
471
527
  BufferLayout.u32('instruction'),
472
528
  BufferLayout.ns64('lamports'),
473
529
  ]),
474
530
  },
475
531
  Withdraw: {
476
532
  index: 4,
477
- layout: BufferLayout.struct([
533
+ layout: BufferLayout.struct<StakeInstructionInputData['Withdraw']>([
478
534
  BufferLayout.u32('instruction'),
479
535
  BufferLayout.ns64('lamports'),
480
536
  ]),
481
537
  },
482
538
  Deactivate: {
483
539
  index: 5,
484
- layout: BufferLayout.struct([BufferLayout.u32('instruction')]),
540
+ layout: BufferLayout.struct<StakeInstructionInputData['Deactivate']>([
541
+ BufferLayout.u32('instruction'),
542
+ ]),
485
543
  },
486
544
  Merge: {
487
545
  index: 7,
488
- layout: BufferLayout.struct([BufferLayout.u32('instruction')]),
546
+ layout: BufferLayout.struct<StakeInstructionInputData['Merge']>([
547
+ BufferLayout.u32('instruction'),
548
+ ]),
489
549
  },
490
550
  AuthorizeWithSeed: {
491
551
  index: 8,
492
- layout: BufferLayout.struct([
493
- BufferLayout.u32('instruction'),
494
- Layout.publicKey('newAuthorized'),
495
- BufferLayout.u32('stakeAuthorizationType'),
496
- Layout.rustString('authoritySeed'),
497
- Layout.publicKey('authorityOwner'),
498
- ]),
552
+ layout: BufferLayout.struct<StakeInstructionInputData['AuthorizeWithSeed']>(
553
+ [
554
+ BufferLayout.u32('instruction'),
555
+ Layout.publicKey('newAuthorized'),
556
+ BufferLayout.u32('stakeAuthorizationType'),
557
+ Layout.rustString('authoritySeed'),
558
+ Layout.publicKey('authorityOwner'),
559
+ ],
560
+ ),
499
561
  },
500
562
  });
501
563
 
@@ -1,6 +1,11 @@
1
1
  import * as BufferLayout from '@solana/buffer-layout';
2
2
 
3
- import {encodeData, decodeData, InstructionType} from './instruction';
3
+ import {
4
+ encodeData,
5
+ decodeData,
6
+ InstructionType,
7
+ IInstructionInputData,
8
+ } from './instruction';
4
9
  import * as Layout from './layout';
5
10
  import {NONCE_ACCOUNT_LENGTH} from './nonce-account';
6
11
  import {PublicKey} from './publickey';
@@ -517,6 +522,10 @@ export class SystemInstruction {
517
522
  * An enumeration of valid SystemInstructionType's
518
523
  */
519
524
  export type SystemInstructionType =
525
+ // FIXME
526
+ // It would be preferable for this type to be `keyof SystemInstructionInputData`
527
+ // but Typedoc does not transpile `keyof` expressions.
528
+ // See https://github.com/TypeStrong/typedoc/issues/1894
520
529
  | 'AdvanceNonceAccount'
521
530
  | 'Allocate'
522
531
  | 'AllocateWithSeed'
@@ -530,16 +539,68 @@ export type SystemInstructionType =
530
539
  | 'TransferWithSeed'
531
540
  | 'WithdrawNonceAccount';
532
541
 
542
+ type SystemInstructionInputData = {
543
+ AdvanceNonceAccount: IInstructionInputData;
544
+ Allocate: IInstructionInputData & {
545
+ space: number;
546
+ };
547
+ AllocateWithSeed: IInstructionInputData & {
548
+ base: Uint8Array;
549
+ programId: Uint8Array;
550
+ seed: string;
551
+ space: number;
552
+ };
553
+ Assign: IInstructionInputData & {
554
+ programId: Uint8Array;
555
+ };
556
+ AssignWithSeed: IInstructionInputData & {
557
+ base: Uint8Array;
558
+ seed: string;
559
+ programId: Uint8Array;
560
+ };
561
+ AuthorizeNonceAccount: IInstructionInputData & {
562
+ authorized: Uint8Array;
563
+ };
564
+ Create: IInstructionInputData & {
565
+ lamports: number;
566
+ programId: Uint8Array;
567
+ space: number;
568
+ };
569
+ CreateWithSeed: IInstructionInputData & {
570
+ base: Uint8Array;
571
+ lamports: number;
572
+ programId: Uint8Array;
573
+ seed: string;
574
+ space: number;
575
+ };
576
+ InitializeNonceAccount: IInstructionInputData & {
577
+ authorized: Uint8Array;
578
+ };
579
+ Transfer: IInstructionInputData & {
580
+ lamports: number;
581
+ };
582
+ TransferWithSeed: IInstructionInputData & {
583
+ lamports: number;
584
+ programId: Uint8Array;
585
+ seed: string;
586
+ };
587
+ WithdrawNonceAccount: IInstructionInputData & {
588
+ lamports: number;
589
+ };
590
+ };
591
+
533
592
  /**
534
593
  * An enumeration of valid system InstructionType's
535
594
  * @internal
536
595
  */
537
- export const SYSTEM_INSTRUCTION_LAYOUTS: {
538
- [type in SystemInstructionType]: InstructionType;
539
- } = Object.freeze({
596
+ export const SYSTEM_INSTRUCTION_LAYOUTS = Object.freeze<{
597
+ [Instruction in SystemInstructionType]: InstructionType<
598
+ SystemInstructionInputData[Instruction]
599
+ >;
600
+ }>({
540
601
  Create: {
541
602
  index: 0,
542
- layout: BufferLayout.struct([
603
+ layout: BufferLayout.struct<SystemInstructionInputData['Create']>([
543
604
  BufferLayout.u32('instruction'),
544
605
  BufferLayout.ns64('lamports'),
545
606
  BufferLayout.ns64('space'),
@@ -548,21 +609,21 @@ export const SYSTEM_INSTRUCTION_LAYOUTS: {
548
609
  },
549
610
  Assign: {
550
611
  index: 1,
551
- layout: BufferLayout.struct([
612
+ layout: BufferLayout.struct<SystemInstructionInputData['Assign']>([
552
613
  BufferLayout.u32('instruction'),
553
614
  Layout.publicKey('programId'),
554
615
  ]),
555
616
  },
556
617
  Transfer: {
557
618
  index: 2,
558
- layout: BufferLayout.struct([
619
+ layout: BufferLayout.struct<SystemInstructionInputData['Transfer']>([
559
620
  BufferLayout.u32('instruction'),
560
621
  BufferLayout.ns64('lamports'),
561
622
  ]),
562
623
  },
563
624
  CreateWithSeed: {
564
625
  index: 3,
565
- layout: BufferLayout.struct([
626
+ layout: BufferLayout.struct<SystemInstructionInputData['CreateWithSeed']>([
566
627
  BufferLayout.u32('instruction'),
567
628
  Layout.publicKey('base'),
568
629
  Layout.rustString('seed'),
@@ -573,49 +634,50 @@ export const SYSTEM_INSTRUCTION_LAYOUTS: {
573
634
  },
574
635
  AdvanceNonceAccount: {
575
636
  index: 4,
576
- layout: BufferLayout.struct([BufferLayout.u32('instruction')]),
637
+ layout: BufferLayout.struct<
638
+ SystemInstructionInputData['AdvanceNonceAccount']
639
+ >([BufferLayout.u32('instruction')]),
577
640
  },
578
641
  WithdrawNonceAccount: {
579
642
  index: 5,
580
- layout: BufferLayout.struct([
581
- BufferLayout.u32('instruction'),
582
- BufferLayout.ns64('lamports'),
583
- ]),
643
+ layout: BufferLayout.struct<
644
+ SystemInstructionInputData['WithdrawNonceAccount']
645
+ >([BufferLayout.u32('instruction'), BufferLayout.ns64('lamports')]),
584
646
  },
585
647
  InitializeNonceAccount: {
586
648
  index: 6,
587
- layout: BufferLayout.struct([
588
- BufferLayout.u32('instruction'),
589
- Layout.publicKey('authorized'),
590
- ]),
649
+ layout: BufferLayout.struct<
650
+ SystemInstructionInputData['InitializeNonceAccount']
651
+ >([BufferLayout.u32('instruction'), Layout.publicKey('authorized')]),
591
652
  },
592
653
  AuthorizeNonceAccount: {
593
654
  index: 7,
594
- layout: BufferLayout.struct([
595
- BufferLayout.u32('instruction'),
596
- Layout.publicKey('authorized'),
597
- ]),
655
+ layout: BufferLayout.struct<
656
+ SystemInstructionInputData['AuthorizeNonceAccount']
657
+ >([BufferLayout.u32('instruction'), Layout.publicKey('authorized')]),
598
658
  },
599
659
  Allocate: {
600
660
  index: 8,
601
- layout: BufferLayout.struct([
661
+ layout: BufferLayout.struct<SystemInstructionInputData['Allocate']>([
602
662
  BufferLayout.u32('instruction'),
603
663
  BufferLayout.ns64('space'),
604
664
  ]),
605
665
  },
606
666
  AllocateWithSeed: {
607
667
  index: 9,
608
- layout: BufferLayout.struct([
609
- BufferLayout.u32('instruction'),
610
- Layout.publicKey('base'),
611
- Layout.rustString('seed'),
612
- BufferLayout.ns64('space'),
613
- Layout.publicKey('programId'),
614
- ]),
668
+ layout: BufferLayout.struct<SystemInstructionInputData['AllocateWithSeed']>(
669
+ [
670
+ BufferLayout.u32('instruction'),
671
+ Layout.publicKey('base'),
672
+ Layout.rustString('seed'),
673
+ BufferLayout.ns64('space'),
674
+ Layout.publicKey('programId'),
675
+ ],
676
+ ),
615
677
  },
616
678
  AssignWithSeed: {
617
679
  index: 10,
618
- layout: BufferLayout.struct([
680
+ layout: BufferLayout.struct<SystemInstructionInputData['AssignWithSeed']>([
619
681
  BufferLayout.u32('instruction'),
620
682
  Layout.publicKey('base'),
621
683
  Layout.rustString('seed'),
@@ -624,12 +686,14 @@ export const SYSTEM_INSTRUCTION_LAYOUTS: {
624
686
  },
625
687
  TransferWithSeed: {
626
688
  index: 11,
627
- layout: BufferLayout.struct([
628
- BufferLayout.u32('instruction'),
629
- BufferLayout.ns64('lamports'),
630
- Layout.rustString('seed'),
631
- Layout.publicKey('programId'),
632
- ]),
689
+ layout: BufferLayout.struct<SystemInstructionInputData['TransferWithSeed']>(
690
+ [
691
+ BufferLayout.u32('instruction'),
692
+ BufferLayout.ns64('lamports'),
693
+ Layout.rustString('seed'),
694
+ Layout.publicKey('programId'),
695
+ ],
696
+ ),
633
697
  },
634
698
  });
635
699
 
@@ -2,6 +2,7 @@ import nacl from 'tweetnacl';
2
2
  import bs58 from 'bs58';
3
3
  import {Buffer} from 'buffer';
4
4
 
5
+ import {Connection} from './connection';
5
6
  import {Message} from './message';
6
7
  import {PublicKey} from './publickey';
7
8
  import * as shortvec from './util/shortvec-encoding';
@@ -405,6 +406,13 @@ export class Transaction {
405
406
  return this._compile().serialize();
406
407
  }
407
408
 
409
+ /**
410
+ * Get the estimated fee associated with a transaction
411
+ */
412
+ async getEstimatedFee(connection: Connection): Promise<number> {
413
+ return (await connection.getFeeForMessage(this.compileMessage())).value;
414
+ }
415
+
408
416
  /**
409
417
  * Specify the public keys which will be used to sign the Transaction.
410
418
  * The first signer will be used as the transaction fee payer account.