@solana/web3.js 0.0.0-next → 0.0.0-pr-29130

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.
Files changed (74) hide show
  1. package/README.md +24 -25
  2. package/lib/index.browser.cjs.js +4583 -4238
  3. package/lib/index.browser.cjs.js.map +1 -1
  4. package/lib/index.browser.esm.js +4565 -4238
  5. package/lib/index.browser.esm.js.map +1 -1
  6. package/lib/index.cjs.js +7072 -3604
  7. package/lib/index.cjs.js.map +1 -1
  8. package/lib/index.d.ts +3516 -2420
  9. package/lib/index.esm.js +7046 -3601
  10. package/lib/index.esm.js.map +1 -1
  11. package/lib/index.iife.js +22171 -27053
  12. package/lib/index.iife.js.map +1 -1
  13. package/lib/index.iife.min.js +8 -33
  14. package/lib/index.iife.min.js.map +1 -1
  15. package/lib/index.native.js +10407 -0
  16. package/lib/index.native.js.map +1 -0
  17. package/package.json +36 -36
  18. package/src/__forks__/browser/fetch-impl.ts +4 -0
  19. package/src/__forks__/react-native/fetch-impl.ts +4 -0
  20. package/src/account-data.ts +39 -0
  21. package/src/account.ts +20 -11
  22. package/src/bpf-loader.ts +2 -2
  23. package/src/connection.ts +2303 -635
  24. package/src/epoch-schedule.ts +1 -1
  25. package/src/errors.ts +41 -0
  26. package/src/fee-calculator.ts +2 -0
  27. package/src/fetch-impl.ts +13 -0
  28. package/src/index.ts +3 -10
  29. package/src/keypair.ts +20 -25
  30. package/src/layout.ts +45 -4
  31. package/src/loader.ts +3 -3
  32. package/src/message/account-keys.ts +79 -0
  33. package/src/message/compiled-keys.ts +165 -0
  34. package/src/message/index.ts +47 -0
  35. package/src/{message.ts → message/legacy.ts} +95 -40
  36. package/src/message/v0.ts +496 -0
  37. package/src/message/versioned.ts +36 -0
  38. package/src/nonce-account.ts +8 -4
  39. package/src/programs/address-lookup-table/index.ts +435 -0
  40. package/src/programs/address-lookup-table/state.ts +84 -0
  41. package/src/programs/compute-budget.ts +281 -0
  42. package/src/{ed25519-program.ts → programs/ed25519.ts} +6 -6
  43. package/src/programs/index.ts +7 -0
  44. package/src/{secp256k1-program.ts → programs/secp256k1.ts} +15 -16
  45. package/src/{stake-program.ts → programs/stake.ts} +7 -7
  46. package/src/{system-program.ts → programs/system.ts} +55 -18
  47. package/src/{vote-program.ts → programs/vote.ts} +137 -9
  48. package/src/publickey.ts +37 -79
  49. package/src/transaction/constants.ts +12 -0
  50. package/src/transaction/expiry-custom-errors.ts +48 -0
  51. package/src/transaction/index.ts +5 -0
  52. package/src/{transaction.ts → transaction/legacy.ts} +162 -67
  53. package/src/transaction/message.ts +140 -0
  54. package/src/transaction/versioned.ts +126 -0
  55. package/src/{util → utils}/assert.ts +0 -0
  56. package/src/utils/bigint.ts +43 -0
  57. package/src/{util → utils}/borsh-schema.ts +0 -0
  58. package/src/{util → utils}/cluster.ts +0 -0
  59. package/src/utils/ed25519.ts +46 -0
  60. package/src/utils/index.ts +5 -0
  61. package/src/utils/makeWebsocketUrl.ts +26 -0
  62. package/src/{util → utils}/promise-timeout.ts +0 -0
  63. package/src/utils/secp256k1.ts +18 -0
  64. package/src/utils/send-and-confirm-raw-transaction.ts +105 -0
  65. package/src/utils/send-and-confirm-transaction.ts +98 -0
  66. package/src/{util → utils}/shortvec-encoding.ts +0 -0
  67. package/src/{util → utils}/sleep.ts +0 -0
  68. package/src/{util → utils}/to-buffer.ts +0 -0
  69. package/src/validator-info.ts +4 -6
  70. package/src/vote-account.ts +1 -1
  71. package/src/agent-manager.ts +0 -44
  72. package/src/util/send-and-confirm-raw-transaction.ts +0 -46
  73. package/src/util/send-and-confirm-transaction.ts +0 -50
  74. package/src/util/url.ts +0 -18
@@ -5,13 +5,13 @@ import {
5
5
  decodeData,
6
6
  InstructionType,
7
7
  IInstructionInputData,
8
- } from './instruction';
9
- import * as Layout from './layout';
10
- import {PublicKey} from './publickey';
11
- import {SystemProgram} from './system-program';
12
- import {SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY} from './sysvar';
13
- import {Transaction, TransactionInstruction} from './transaction';
14
- import {toBuffer} from './util/to-buffer';
8
+ } from '../instruction';
9
+ import * as Layout from '../layout';
10
+ import {PublicKey} from '../publickey';
11
+ import {SystemProgram} from './system';
12
+ import {SYSVAR_CLOCK_PUBKEY, SYSVAR_RENT_PUBKEY} from '../sysvar';
13
+ import {Transaction, TransactionInstruction} from '../transaction';
14
+ import {toBuffer} from '../utils/to-buffer';
15
15
 
16
16
  /**
17
17
  * Vote account info
@@ -65,6 +65,18 @@ export type AuthorizeVoteParams = {
65
65
  voteAuthorizationType: VoteAuthorizationType;
66
66
  };
67
67
 
68
+ /**
69
+ * AuthorizeWithSeed instruction params
70
+ */
71
+ export type AuthorizeVoteWithSeedParams = {
72
+ currentAuthorityDerivedKeyBasePubkey: PublicKey;
73
+ currentAuthorityDerivedKeyOwnerPubkey: PublicKey;
74
+ currentAuthorityDerivedKeySeed: string;
75
+ newAuthorizedPubkey: PublicKey;
76
+ voteAuthorizationType: VoteAuthorizationType;
77
+ votePubkey: PublicKey;
78
+ };
79
+
68
80
  /**
69
81
  * Withdraw from vote account transaction params
70
82
  */
@@ -160,6 +172,41 @@ export class VoteInstruction {
160
172
  };
161
173
  }
162
174
 
175
+ /**
176
+ * Decode an authorize instruction and retrieve the instruction params.
177
+ */
178
+ static decodeAuthorizeWithSeed(
179
+ instruction: TransactionInstruction,
180
+ ): AuthorizeVoteWithSeedParams {
181
+ this.checkProgramId(instruction.programId);
182
+ this.checkKeyLength(instruction.keys, 3);
183
+
184
+ const {
185
+ voteAuthorizeWithSeedArgs: {
186
+ currentAuthorityDerivedKeyOwnerPubkey,
187
+ currentAuthorityDerivedKeySeed,
188
+ newAuthorized,
189
+ voteAuthorizationType,
190
+ },
191
+ } = decodeData(
192
+ VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed,
193
+ instruction.data,
194
+ );
195
+
196
+ return {
197
+ currentAuthorityDerivedKeyBasePubkey: instruction.keys[2].pubkey,
198
+ currentAuthorityDerivedKeyOwnerPubkey: new PublicKey(
199
+ currentAuthorityDerivedKeyOwnerPubkey,
200
+ ),
201
+ currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
202
+ newAuthorizedPubkey: new PublicKey(newAuthorized),
203
+ voteAuthorizationType: {
204
+ index: voteAuthorizationType,
205
+ },
206
+ votePubkey: instruction.keys[0].pubkey,
207
+ };
208
+ }
209
+
163
210
  /**
164
211
  * Decode a withdraw instruction and retrieve the instruction params.
165
212
  */
@@ -211,13 +258,23 @@ export type VoteInstructionType =
211
258
  // It would be preferable for this type to be `keyof VoteInstructionInputData`
212
259
  // but Typedoc does not transpile `keyof` expressions.
213
260
  // See https://github.com/TypeStrong/typedoc/issues/1894
214
- 'Authorize' | 'InitializeAccount' | 'Withdraw';
215
-
261
+ 'Authorize' | 'AuthorizeWithSeed' | 'InitializeAccount' | 'Withdraw';
262
+
263
+ /** @internal */
264
+ export type VoteAuthorizeWithSeedArgs = Readonly<{
265
+ currentAuthorityDerivedKeyOwnerPubkey: Uint8Array;
266
+ currentAuthorityDerivedKeySeed: string;
267
+ newAuthorized: Uint8Array;
268
+ voteAuthorizationType: number;
269
+ }>;
216
270
  type VoteInstructionInputData = {
217
271
  Authorize: IInstructionInputData & {
218
272
  newAuthorized: Uint8Array;
219
273
  voteAuthorizationType: number;
220
274
  };
275
+ AuthorizeWithSeed: IInstructionInputData & {
276
+ voteAuthorizeWithSeedArgs: VoteAuthorizeWithSeedArgs;
277
+ };
221
278
  InitializeAccount: IInstructionInputData & {
222
279
  voteInit: Readonly<{
223
280
  authorizedVoter: Uint8Array;
@@ -258,6 +315,13 @@ const VOTE_INSTRUCTION_LAYOUTS = Object.freeze<{
258
315
  BufferLayout.ns64('lamports'),
259
316
  ]),
260
317
  },
318
+ AuthorizeWithSeed: {
319
+ index: 10,
320
+ layout: BufferLayout.struct<VoteInstructionInputData['AuthorizeWithSeed']>([
321
+ BufferLayout.u32('instruction'),
322
+ Layout.voteAuthorizeWithSeedArgs(),
323
+ ]),
324
+ },
261
325
  });
262
326
 
263
327
  /**
@@ -390,6 +454,49 @@ export class VoteProgram {
390
454
  });
391
455
  }
392
456
 
457
+ /**
458
+ * Generate a transaction that authorizes a new Voter or Withdrawer on the Vote account
459
+ * where the current Voter or Withdrawer authority is a derived key.
460
+ */
461
+ static authorizeWithSeed(params: AuthorizeVoteWithSeedParams): Transaction {
462
+ const {
463
+ currentAuthorityDerivedKeyBasePubkey,
464
+ currentAuthorityDerivedKeyOwnerPubkey,
465
+ currentAuthorityDerivedKeySeed,
466
+ newAuthorizedPubkey,
467
+ voteAuthorizationType,
468
+ votePubkey,
469
+ } = params;
470
+
471
+ const type = VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed;
472
+ const data = encodeData(type, {
473
+ voteAuthorizeWithSeedArgs: {
474
+ currentAuthorityDerivedKeyOwnerPubkey: toBuffer(
475
+ currentAuthorityDerivedKeyOwnerPubkey.toBuffer(),
476
+ ),
477
+ currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
478
+ newAuthorized: toBuffer(newAuthorizedPubkey.toBuffer()),
479
+ voteAuthorizationType: voteAuthorizationType.index,
480
+ },
481
+ });
482
+
483
+ const keys = [
484
+ {pubkey: votePubkey, isSigner: false, isWritable: true},
485
+ {pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
486
+ {
487
+ pubkey: currentAuthorityDerivedKeyBasePubkey,
488
+ isSigner: true,
489
+ isWritable: false,
490
+ },
491
+ ];
492
+
493
+ return new Transaction().add({
494
+ keys,
495
+ programId: this.programId,
496
+ data,
497
+ });
498
+ }
499
+
393
500
  /**
394
501
  * Generate a transaction to withdraw from a Vote account.
395
502
  */
@@ -410,4 +517,25 @@ export class VoteProgram {
410
517
  data,
411
518
  });
412
519
  }
520
+
521
+ /**
522
+ * Generate a transaction to withdraw safely from a Vote account.
523
+ *
524
+ * This function was created as a safeguard for vote accounts running validators, `safeWithdraw`
525
+ * checks that the withdraw amount will not exceed the specified balance while leaving enough left
526
+ * to cover rent. If you wish to close the vote account by withdrawing the full amount, call the
527
+ * `withdraw` method directly.
528
+ */
529
+ static safeWithdraw(
530
+ params: WithdrawFromVoteAccountParams,
531
+ currentVoteAccountBalance: number,
532
+ rentExemptMinimum: number,
533
+ ): Transaction {
534
+ if (params.lamports > currentVoteAccountBalance - rentExemptMinimum) {
535
+ throw new Error(
536
+ 'Withdraw will leave vote account with insuffcient funds.',
537
+ );
538
+ }
539
+ return VoteProgram.withdraw(params);
540
+ }
413
541
  }
package/src/publickey.ts CHANGED
@@ -1,24 +1,28 @@
1
1
  import BN from 'bn.js';
2
2
  import bs58 from 'bs58';
3
3
  import {Buffer} from 'buffer';
4
- import nacl from 'tweetnacl';
5
- import {sha256} from '@ethersproject/sha2';
4
+ import {sha256} from '@noble/hashes/sha256';
6
5
 
7
- import {Struct, SOLANA_SCHEMA} from './util/borsh-schema';
8
- import {toBuffer} from './util/to-buffer';
6
+ import {isOnCurve} from './utils/ed25519';
7
+ import {Struct, SOLANA_SCHEMA} from './utils/borsh-schema';
8
+ import {toBuffer} from './utils/to-buffer';
9
9
 
10
10
  /**
11
11
  * Maximum length of derived pubkey seed
12
12
  */
13
13
  export const MAX_SEED_LENGTH = 32;
14
14
 
15
+ /**
16
+ * Size of public key in bytes
17
+ */
18
+ export const PUBLIC_KEY_LENGTH = 32;
19
+
15
20
  /**
16
21
  * Value to be converted into public key
17
22
  */
18
23
  export type PublicKeyInitData =
19
24
  | number
20
25
  | string
21
- | Buffer
22
26
  | Uint8Array
23
27
  | Array<number>
24
28
  | PublicKeyData;
@@ -35,6 +39,9 @@ function isPublicKeyData(value: PublicKeyInitData): value is PublicKeyData {
35
39
  return (value as PublicKeyData)._bn !== undefined;
36
40
  }
37
41
 
42
+ // local counter used by PublicKey.unique()
43
+ let uniquePublicKeyCounter = 1;
44
+
38
45
  /**
39
46
  * A public key
40
47
  */
@@ -54,7 +61,7 @@ export class PublicKey extends Struct {
54
61
  if (typeof value === 'string') {
55
62
  // assume base 58 encoding by default
56
63
  const decoded = bs58.decode(value);
57
- if (decoded.length != 32) {
64
+ if (decoded.length != PUBLIC_KEY_LENGTH) {
58
65
  throw new Error(`Invalid public key input`);
59
66
  }
60
67
  this._bn = new BN(decoded);
@@ -62,14 +69,24 @@ export class PublicKey extends Struct {
62
69
  this._bn = new BN(value);
63
70
  }
64
71
 
65
- if (this._bn.byteLength() > 32) {
72
+ if (this._bn.byteLength() > PUBLIC_KEY_LENGTH) {
66
73
  throw new Error(`Invalid public key input`);
67
74
  }
68
75
  }
69
76
  }
70
77
 
71
78
  /**
72
- * Default public key value. (All zeros)
79
+ * Returns a unique PublicKey for tests and benchmarks using a counter
80
+ */
81
+ static unique(): PublicKey {
82
+ const key = new PublicKey(uniquePublicKeyCounter);
83
+ uniquePublicKeyCounter += 1;
84
+ return new PublicKey(key.toBuffer());
85
+ }
86
+
87
+ /**
88
+ * Default public key value. The base58-encoded string representation is all ones (as seen below)
89
+ * The underlying BN number is 32 bytes that are all zeros
73
90
  */
74
91
  static default: PublicKey = new PublicKey('11111111111111111111111111111111');
75
92
 
@@ -103,7 +120,7 @@ export class PublicKey extends Struct {
103
120
  */
104
121
  toBuffer(): Buffer {
105
122
  const b = this._bn.toArrayLike(Buffer);
106
- if (b.length === 32) {
123
+ if (b.length === PUBLIC_KEY_LENGTH) {
107
124
  return b;
108
125
  }
109
126
 
@@ -135,8 +152,8 @@ export class PublicKey extends Struct {
135
152
  Buffer.from(seed),
136
153
  programId.toBuffer(),
137
154
  ]);
138
- const hash = sha256(new Uint8Array(buffer)).slice(2);
139
- return new PublicKey(Buffer.from(hash, 'hex'));
155
+ const publicKeyBytes = sha256(buffer);
156
+ return new PublicKey(publicKeyBytes);
140
157
  }
141
158
 
142
159
  /**
@@ -159,9 +176,8 @@ export class PublicKey extends Struct {
159
176
  programId.toBuffer(),
160
177
  Buffer.from('ProgramDerivedAddress'),
161
178
  ]);
162
- let hash = sha256(new Uint8Array(buffer)).slice(2);
163
- let publicKeyBytes = new BN(hash, 16).toArray(undefined, 32);
164
- if (is_on_curve(publicKeyBytes)) {
179
+ const publicKeyBytes = sha256(buffer);
180
+ if (isOnCurve(publicKeyBytes)) {
165
181
  throw new Error(`Invalid seeds, address must fall off the curve`);
166
182
  }
167
183
  return new PublicKey(publicKeyBytes);
@@ -170,6 +186,8 @@ export class PublicKey extends Struct {
170
186
  /**
171
187
  * Async version of createProgramAddressSync
172
188
  * For backwards compatibility
189
+ *
190
+ * @deprecated Use {@link createProgramAddressSync} instead
173
191
  */
174
192
  /* eslint-disable require-await */
175
193
  static async createProgramAddress(
@@ -211,6 +229,8 @@ export class PublicKey extends Struct {
211
229
  /**
212
230
  * Async version of findProgramAddressSync
213
231
  * For backwards compatibility
232
+ *
233
+ * @deprecated Use {@link findProgramAddressSync} instead
214
234
  */
215
235
  static async findProgramAddress(
216
236
  seeds: Array<Buffer | Uint8Array>,
@@ -222,8 +242,9 @@ export class PublicKey extends Struct {
222
242
  /**
223
243
  * Check that a pubkey is on the ed25519 curve.
224
244
  */
225
- static isOnCurve(pubkey: Uint8Array): boolean {
226
- return is_on_curve(pubkey) == 1;
245
+ static isOnCurve(pubkeyData: PublicKeyInitData): boolean {
246
+ const pubkey = new PublicKey(pubkeyData);
247
+ return isOnCurve(pubkey.toBytes());
227
248
  }
228
249
  }
229
250
 
@@ -231,66 +252,3 @@ SOLANA_SCHEMA.set(PublicKey, {
231
252
  kind: 'struct',
232
253
  fields: [['_bn', 'u256']],
233
254
  });
234
-
235
- // @ts-ignore
236
- let naclLowLevel = nacl.lowlevel;
237
-
238
- // Check that a pubkey is on the curve.
239
- // This function and its dependents were sourced from:
240
- // https://github.com/dchest/tweetnacl-js/blob/f1ec050ceae0861f34280e62498b1d3ed9c350c6/nacl.js#L792
241
- function is_on_curve(p: any) {
242
- var r = [
243
- naclLowLevel.gf(),
244
- naclLowLevel.gf(),
245
- naclLowLevel.gf(),
246
- naclLowLevel.gf(),
247
- ];
248
-
249
- var t = naclLowLevel.gf(),
250
- chk = naclLowLevel.gf(),
251
- num = naclLowLevel.gf(),
252
- den = naclLowLevel.gf(),
253
- den2 = naclLowLevel.gf(),
254
- den4 = naclLowLevel.gf(),
255
- den6 = naclLowLevel.gf();
256
-
257
- naclLowLevel.set25519(r[2], gf1);
258
- naclLowLevel.unpack25519(r[1], p);
259
- naclLowLevel.S(num, r[1]);
260
- naclLowLevel.M(den, num, naclLowLevel.D);
261
- naclLowLevel.Z(num, num, r[2]);
262
- naclLowLevel.A(den, r[2], den);
263
-
264
- naclLowLevel.S(den2, den);
265
- naclLowLevel.S(den4, den2);
266
- naclLowLevel.M(den6, den4, den2);
267
- naclLowLevel.M(t, den6, num);
268
- naclLowLevel.M(t, t, den);
269
-
270
- naclLowLevel.pow2523(t, t);
271
- naclLowLevel.M(t, t, num);
272
- naclLowLevel.M(t, t, den);
273
- naclLowLevel.M(t, t, den);
274
- naclLowLevel.M(r[0], t, den);
275
-
276
- naclLowLevel.S(chk, r[0]);
277
- naclLowLevel.M(chk, chk, den);
278
- if (neq25519(chk, num)) naclLowLevel.M(r[0], r[0], I);
279
-
280
- naclLowLevel.S(chk, r[0]);
281
- naclLowLevel.M(chk, chk, den);
282
- if (neq25519(chk, num)) return 0;
283
- return 1;
284
- }
285
- let gf1 = naclLowLevel.gf([1]);
286
- let I = naclLowLevel.gf([
287
- 0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7,
288
- 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83,
289
- ]);
290
- function neq25519(a: any, b: any) {
291
- var c = new Uint8Array(32),
292
- d = new Uint8Array(32);
293
- naclLowLevel.pack25519(c, a);
294
- naclLowLevel.pack25519(d, b);
295
- return naclLowLevel.crypto_verify_32(c, 0, d, 0);
296
- }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Maximum over-the-wire size of a Transaction
3
+ *
4
+ * 1280 is IPv6 minimum MTU
5
+ * 40 bytes is the size of the IPv6 header
6
+ * 8 bytes is the size of the fragment header
7
+ */
8
+ export const PACKET_DATA_SIZE = 1280 - 40 - 8;
9
+
10
+ export const VERSION_PREFIX_MASK = 0x7f;
11
+
12
+ export const SIGNATURE_LENGTH_IN_BYTES = 64;
@@ -0,0 +1,48 @@
1
+ export class TransactionExpiredBlockheightExceededError extends Error {
2
+ signature: string;
3
+
4
+ constructor(signature: string) {
5
+ super(`Signature ${signature} has expired: block height exceeded.`);
6
+ this.signature = signature;
7
+ }
8
+ }
9
+
10
+ Object.defineProperty(
11
+ TransactionExpiredBlockheightExceededError.prototype,
12
+ 'name',
13
+ {
14
+ value: 'TransactionExpiredBlockheightExceededError',
15
+ },
16
+ );
17
+
18
+ export class TransactionExpiredTimeoutError extends Error {
19
+ signature: string;
20
+
21
+ constructor(signature: string, timeoutSeconds: number) {
22
+ super(
23
+ `Transaction was not confirmed in ${timeoutSeconds.toFixed(
24
+ 2,
25
+ )} seconds. It is ` +
26
+ 'unknown if it succeeded or failed. Check signature ' +
27
+ `${signature} using the Solana Explorer or CLI tools.`,
28
+ );
29
+ this.signature = signature;
30
+ }
31
+ }
32
+
33
+ Object.defineProperty(TransactionExpiredTimeoutError.prototype, 'name', {
34
+ value: 'TransactionExpiredTimeoutError',
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
+ });
@@ -0,0 +1,5 @@
1
+ export * from './constants';
2
+ export * from './expiry-custom-errors';
3
+ export * from './legacy';
4
+ export * from './message';
5
+ export * from './versioned';