@solana/web3.js 1.47.3 → 1.49.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solana/web3.js",
3
- "version": "1.47.3",
3
+ "version": "1.49.0",
4
4
  "description": "Solana Javascript API",
5
5
  "keywords": [
6
6
  "api",
@@ -23,6 +23,7 @@
23
23
  "./lib/index.cjs.js": "./lib/index.browser.cjs.js",
24
24
  "./lib/index.esm.js": "./lib/index.browser.esm.js"
25
25
  },
26
+ "react-native": "lib/index.native.js",
26
27
  "main": "lib/index.cjs.js",
27
28
  "module": "lib/index.esm.js",
28
29
  "types": "lib/index.d.ts",
@@ -68,6 +69,7 @@
68
69
  "jayson": "^3.4.4",
69
70
  "js-sha3": "^0.8.0",
70
71
  "node-fetch": "2",
72
+ "react-native-url-polyfill": "^1.3.0",
71
73
  "rpc-websockets": "^7.5.0",
72
74
  "secp256k1": "^4.0.2",
73
75
  "superstruct": "^0.14.2",
@@ -0,0 +1,4 @@
1
+ export const Headers = globalThis.Headers;
2
+ export const Request = globalThis.Request;
3
+ export const Response = globalThis.Response;
4
+ export default globalThis.fetch;
@@ -0,0 +1,433 @@
1
+ import {toBufferLE} from 'bigint-buffer';
2
+ import * as BufferLayout from '@solana/buffer-layout';
3
+
4
+ import * as Layout from './layout';
5
+ import {PublicKey} from './publickey';
6
+ import * as bigintLayout from './util/bigint';
7
+ import {SystemProgram} from './system-program';
8
+ import {TransactionInstruction} from './transaction';
9
+ import {decodeData, encodeData, IInstructionInputData} from './instruction';
10
+
11
+ export type CreateLookupTableParams = {
12
+ /** Account used to derive and control the new address lookup table. */
13
+ authority: PublicKey;
14
+ /** Account that will fund the new address lookup table. */
15
+ payer: PublicKey;
16
+ /** A recent slot must be used in the derivation path for each initialized table. */
17
+ recentSlot: bigint | number;
18
+ };
19
+
20
+ export type FreezeLookupTableParams = {
21
+ /** Address lookup table account to freeze. */
22
+ lookupTable: PublicKey;
23
+ /** Account which is the current authority. */
24
+ authority: PublicKey;
25
+ };
26
+
27
+ export type ExtendLookupTableParams = {
28
+ /** Address lookup table account to extend. */
29
+ lookupTable: PublicKey;
30
+ /** Account which is the current authority. */
31
+ authority: PublicKey;
32
+ /** Account that will fund the table reallocation.
33
+ * Not required if the reallocation has already been funded. */
34
+ payer?: PublicKey;
35
+ /** List of Public Keys to be added to the lookup table. */
36
+ addresses: Array<PublicKey>;
37
+ };
38
+
39
+ export type DeactivateLookupTableParams = {
40
+ /** Address lookup table account to deactivate. */
41
+ lookupTable: PublicKey;
42
+ /** Account which is the current authority. */
43
+ authority: PublicKey;
44
+ };
45
+
46
+ export type CloseLookupTableParams = {
47
+ /** Address lookup table account to close. */
48
+ lookupTable: PublicKey;
49
+ /** Account which is the current authority. */
50
+ authority: PublicKey;
51
+ /** Recipient of closed account lamports. */
52
+ recipient: PublicKey;
53
+ };
54
+
55
+ /**
56
+ * An enumeration of valid LookupTableInstructionType's
57
+ */
58
+ export type LookupTableInstructionType =
59
+ | 'CreateLookupTable'
60
+ | 'ExtendLookupTable'
61
+ | 'CloseLookupTable'
62
+ | 'FreezeLookupTable'
63
+ | 'DeactivateLookupTable';
64
+
65
+ type LookupTableInstructionInputData = {
66
+ CreateLookupTable: IInstructionInputData &
67
+ Readonly<{
68
+ recentSlot: bigint;
69
+ bumpSeed: number;
70
+ }>;
71
+ FreezeLookupTable: IInstructionInputData;
72
+ ExtendLookupTable: IInstructionInputData &
73
+ Readonly<{
74
+ numberOfAddresses: bigint;
75
+ addresses: Array<Uint8Array>;
76
+ }>;
77
+ DeactivateLookupTable: IInstructionInputData;
78
+ CloseLookupTable: IInstructionInputData;
79
+ };
80
+
81
+ /**
82
+ * An enumeration of valid address lookup table InstructionType's
83
+ * @internal
84
+ */
85
+ export const LOOKUP_TABLE_INSTRUCTION_LAYOUTS = Object.freeze({
86
+ CreateLookupTable: {
87
+ index: 0,
88
+ layout: BufferLayout.struct<
89
+ LookupTableInstructionInputData['CreateLookupTable']
90
+ >([
91
+ BufferLayout.u32('instruction'),
92
+ bigintLayout.u64('recentSlot'),
93
+ BufferLayout.u8('bumpSeed'),
94
+ ]),
95
+ },
96
+ FreezeLookupTable: {
97
+ index: 1,
98
+ layout: BufferLayout.struct<
99
+ LookupTableInstructionInputData['FreezeLookupTable']
100
+ >([BufferLayout.u32('instruction')]),
101
+ },
102
+ ExtendLookupTable: {
103
+ index: 2,
104
+ layout: BufferLayout.struct<
105
+ LookupTableInstructionInputData['ExtendLookupTable']
106
+ >([
107
+ BufferLayout.u32('instruction'),
108
+ bigintLayout.u64(),
109
+ BufferLayout.seq(
110
+ Layout.publicKey(),
111
+ BufferLayout.offset(BufferLayout.u32(), -8),
112
+ 'addresses',
113
+ ),
114
+ ]),
115
+ },
116
+ DeactivateLookupTable: {
117
+ index: 3,
118
+ layout: BufferLayout.struct<
119
+ LookupTableInstructionInputData['DeactivateLookupTable']
120
+ >([BufferLayout.u32('instruction')]),
121
+ },
122
+ CloseLookupTable: {
123
+ index: 4,
124
+ layout: BufferLayout.struct<
125
+ LookupTableInstructionInputData['CloseLookupTable']
126
+ >([BufferLayout.u32('instruction')]),
127
+ },
128
+ });
129
+
130
+ export class AddressLookupTableInstruction {
131
+ /**
132
+ * @internal
133
+ */
134
+ constructor() {}
135
+
136
+ static decodeInstructionType(
137
+ instruction: TransactionInstruction,
138
+ ): LookupTableInstructionType {
139
+ this.checkProgramId(instruction.programId);
140
+
141
+ const instructionTypeLayout = BufferLayout.u32('instruction');
142
+ const index = instructionTypeLayout.decode(instruction.data);
143
+
144
+ let type: LookupTableInstructionType | undefined;
145
+ for (const [layoutType, layout] of Object.entries(
146
+ LOOKUP_TABLE_INSTRUCTION_LAYOUTS,
147
+ )) {
148
+ if ((layout as any).index == index) {
149
+ type = layoutType as LookupTableInstructionType;
150
+ break;
151
+ }
152
+ }
153
+ if (!type) {
154
+ throw new Error(
155
+ 'Invalid Instruction. Should be a LookupTable Instruction',
156
+ );
157
+ }
158
+ return type;
159
+ }
160
+
161
+ static decodeCreateLookupTable(
162
+ instruction: TransactionInstruction,
163
+ ): CreateLookupTableParams {
164
+ this.checkProgramId(instruction.programId);
165
+ this.checkKeysLength(instruction.keys, 4);
166
+
167
+ const {recentSlot} = decodeData(
168
+ LOOKUP_TABLE_INSTRUCTION_LAYOUTS.CreateLookupTable,
169
+ instruction.data,
170
+ );
171
+
172
+ return {
173
+ authority: instruction.keys[1].pubkey,
174
+ payer: instruction.keys[2].pubkey,
175
+ recentSlot: Number(recentSlot),
176
+ };
177
+ }
178
+
179
+ static decodeExtendLookupTable(
180
+ instruction: TransactionInstruction,
181
+ ): ExtendLookupTableParams {
182
+ this.checkProgramId(instruction.programId);
183
+ if (instruction.keys.length < 2) {
184
+ throw new Error(
185
+ `invalid instruction; found ${instruction.keys.length} keys, expected at least 2`,
186
+ );
187
+ }
188
+
189
+ const {addresses} = decodeData(
190
+ LOOKUP_TABLE_INSTRUCTION_LAYOUTS.ExtendLookupTable,
191
+ instruction.data,
192
+ );
193
+ return {
194
+ lookupTable: instruction.keys[0].pubkey,
195
+ authority: instruction.keys[1].pubkey,
196
+ payer:
197
+ instruction.keys.length > 2 ? instruction.keys[2].pubkey : undefined,
198
+ addresses: addresses.map(buffer => new PublicKey(buffer)),
199
+ };
200
+ }
201
+
202
+ static decodeCloseLookupTable(
203
+ instruction: TransactionInstruction,
204
+ ): CloseLookupTableParams {
205
+ this.checkProgramId(instruction.programId);
206
+ this.checkKeysLength(instruction.keys, 3);
207
+
208
+ return {
209
+ lookupTable: instruction.keys[0].pubkey,
210
+ authority: instruction.keys[1].pubkey,
211
+ recipient: instruction.keys[2].pubkey,
212
+ };
213
+ }
214
+
215
+ static decodeFreezeLookupTable(
216
+ instruction: TransactionInstruction,
217
+ ): FreezeLookupTableParams {
218
+ this.checkProgramId(instruction.programId);
219
+ this.checkKeysLength(instruction.keys, 2);
220
+
221
+ return {
222
+ lookupTable: instruction.keys[0].pubkey,
223
+ authority: instruction.keys[1].pubkey,
224
+ };
225
+ }
226
+
227
+ static decodeDeactivateLookupTable(
228
+ instruction: TransactionInstruction,
229
+ ): DeactivateLookupTableParams {
230
+ this.checkProgramId(instruction.programId);
231
+ this.checkKeysLength(instruction.keys, 2);
232
+
233
+ return {
234
+ lookupTable: instruction.keys[0].pubkey,
235
+ authority: instruction.keys[1].pubkey,
236
+ };
237
+ }
238
+
239
+ /**
240
+ * @internal
241
+ */
242
+ static checkProgramId(programId: PublicKey) {
243
+ if (!programId.equals(AddressLookupTableProgram.programId)) {
244
+ throw new Error(
245
+ 'invalid instruction; programId is not AddressLookupTable Program',
246
+ );
247
+ }
248
+ }
249
+ /**
250
+ * @internal
251
+ */
252
+ static checkKeysLength(keys: Array<any>, expectedLength: number) {
253
+ if (keys.length < expectedLength) {
254
+ throw new Error(
255
+ `invalid instruction; found ${keys.length} keys, expected at least ${expectedLength}`,
256
+ );
257
+ }
258
+ }
259
+ }
260
+
261
+ export class AddressLookupTableProgram {
262
+ /**
263
+ * @internal
264
+ */
265
+ constructor() {}
266
+
267
+ static programId: PublicKey = new PublicKey(
268
+ 'AddressLookupTab1e1111111111111111111111111',
269
+ );
270
+
271
+ static createLookupTable(params: CreateLookupTableParams) {
272
+ const [lookupTableAddress, bumpSeed] = PublicKey.findProgramAddressSync(
273
+ [params.authority.toBuffer(), toBufferLE(BigInt(params.recentSlot), 8)],
274
+ this.programId,
275
+ );
276
+
277
+ const type = LOOKUP_TABLE_INSTRUCTION_LAYOUTS.CreateLookupTable;
278
+ const data = encodeData(type, {
279
+ recentSlot: BigInt(params.recentSlot),
280
+ bumpSeed: bumpSeed,
281
+ });
282
+
283
+ const keys = [
284
+ {
285
+ pubkey: lookupTableAddress,
286
+ isSigner: false,
287
+ isWritable: true,
288
+ },
289
+ {
290
+ pubkey: params.authority,
291
+ isSigner: true,
292
+ isWritable: false,
293
+ },
294
+ {
295
+ pubkey: params.payer,
296
+ isSigner: true,
297
+ isWritable: true,
298
+ },
299
+ {
300
+ pubkey: SystemProgram.programId,
301
+ isSigner: false,
302
+ isWritable: false,
303
+ },
304
+ ];
305
+
306
+ return [
307
+ new TransactionInstruction({
308
+ programId: this.programId,
309
+ keys: keys,
310
+ data: data,
311
+ }),
312
+ lookupTableAddress,
313
+ ] as [TransactionInstruction, PublicKey];
314
+ }
315
+
316
+ static freezeLookupTable(params: FreezeLookupTableParams) {
317
+ const type = LOOKUP_TABLE_INSTRUCTION_LAYOUTS.FreezeLookupTable;
318
+ const data = encodeData(type);
319
+
320
+ const keys = [
321
+ {
322
+ pubkey: params.lookupTable,
323
+ isSigner: false,
324
+ isWritable: true,
325
+ },
326
+ {
327
+ pubkey: params.authority,
328
+ isSigner: true,
329
+ isWritable: false,
330
+ },
331
+ ];
332
+
333
+ return new TransactionInstruction({
334
+ programId: this.programId,
335
+ keys: keys,
336
+ data: data,
337
+ });
338
+ }
339
+
340
+ static extendLookupTable(params: ExtendLookupTableParams) {
341
+ const type = LOOKUP_TABLE_INSTRUCTION_LAYOUTS.ExtendLookupTable;
342
+ const data = encodeData(type, {
343
+ addresses: params.addresses.map(addr => addr.toBytes()),
344
+ });
345
+
346
+ const keys = [
347
+ {
348
+ pubkey: params.lookupTable,
349
+ isSigner: false,
350
+ isWritable: true,
351
+ },
352
+ {
353
+ pubkey: params.authority,
354
+ isSigner: true,
355
+ isWritable: false,
356
+ },
357
+ ];
358
+
359
+ if (params.payer) {
360
+ keys.push(
361
+ {
362
+ pubkey: params.payer,
363
+ isSigner: true,
364
+ isWritable: true,
365
+ },
366
+ {
367
+ pubkey: SystemProgram.programId,
368
+ isSigner: false,
369
+ isWritable: false,
370
+ },
371
+ );
372
+ }
373
+
374
+ return new TransactionInstruction({
375
+ programId: this.programId,
376
+ keys: keys,
377
+ data: data,
378
+ });
379
+ }
380
+
381
+ static deactivateLookupTable(params: DeactivateLookupTableParams) {
382
+ const type = LOOKUP_TABLE_INSTRUCTION_LAYOUTS.DeactivateLookupTable;
383
+ const data = encodeData(type);
384
+
385
+ const keys = [
386
+ {
387
+ pubkey: params.lookupTable,
388
+ isSigner: false,
389
+ isWritable: true,
390
+ },
391
+ {
392
+ pubkey: params.authority,
393
+ isSigner: true,
394
+ isWritable: false,
395
+ },
396
+ ];
397
+
398
+ return new TransactionInstruction({
399
+ programId: this.programId,
400
+ keys: keys,
401
+ data: data,
402
+ });
403
+ }
404
+
405
+ static closeLookupTable(params: CloseLookupTableParams) {
406
+ const type = LOOKUP_TABLE_INSTRUCTION_LAYOUTS.CloseLookupTable;
407
+ const data = encodeData(type);
408
+
409
+ const keys = [
410
+ {
411
+ pubkey: params.lookupTable,
412
+ isSigner: false,
413
+ isWritable: true,
414
+ },
415
+ {
416
+ pubkey: params.authority,
417
+ isSigner: true,
418
+ isWritable: false,
419
+ },
420
+ {
421
+ pubkey: params.recipient,
422
+ isSigner: false,
423
+ isWritable: true,
424
+ },
425
+ ];
426
+
427
+ return new TransactionInstruction({
428
+ programId: this.programId,
429
+ keys: keys,
430
+ data: data,
431
+ });
432
+ }
433
+ }
package/src/connection.ts CHANGED
@@ -24,6 +24,7 @@ import type {Struct} from 'superstruct';
24
24
  import {Client as RpcWebSocketClient} from 'rpc-websockets';
25
25
  import RpcClient from 'jayson/lib/client/browser';
26
26
 
27
+ import {URL} from './util/url-impl';
27
28
  import {AgentManager} from './agent-manager';
28
29
  import {EpochSchedule} from './epoch-schedule';
29
30
  import {SendTransactionError, SolanaJSONRPCError} from './errors';
@@ -41,7 +42,7 @@ import {
41
42
  TransactionExpiredBlockheightExceededError,
42
43
  TransactionExpiredTimeoutError,
43
44
  } from './util/tx-expiry-custom-errors';
44
- import {makeWebsocketUrl} from './util/url';
45
+ import {makeWebsocketUrl} from './util/makeWebsocketUrl';
45
46
  import type {Blockhash} from './blockhash';
46
47
  import type {FeeCalculator} from './fee-calculator';
47
48
  import type {TransactionSignature} from './transaction';
@@ -442,6 +443,16 @@ export type GetBalanceConfig = {
442
443
  minContextSlot?: number;
443
444
  };
444
445
 
446
+ /**
447
+ * Configuration object for changing `getBlock` query behavior
448
+ */
449
+ export type GetBlockConfig = {
450
+ /** The level of finality desired */
451
+ commitment?: Finality;
452
+ /** The max transaction version to return in responses. If the requested transaction is a higher version, an error will be returned */
453
+ maxSupportedTransactionVersion?: number;
454
+ };
455
+
445
456
  /**
446
457
  * Configuration object for changing `getBlockHeight` query behavior
447
458
  */
@@ -504,6 +515,16 @@ export type GetSlotLeaderConfig = {
504
515
  minContextSlot?: number;
505
516
  };
506
517
 
518
+ /**
519
+ * Configuration object for changing `getTransaction` query behavior
520
+ */
521
+ export type GetTransactionConfig = {
522
+ /** The level of finality desired */
523
+ commitment?: Finality;
524
+ /** The max transaction version to return in responses. If the requested transaction is a higher version, an error will be returned */
525
+ maxSupportedTransactionVersion?: number;
526
+ };
527
+
507
528
  /**
508
529
  * Configuration object for changing `getLargestAccounts` query behavior
509
530
  */
@@ -711,13 +732,20 @@ export type SimulatedTransactionAccountInfo = {
711
732
  rentEpoch?: number;
712
733
  };
713
734
 
735
+ export type TransactionReturnDataEncoding = 'base64';
736
+
737
+ export type TransactionReturnData = {
738
+ programId: string;
739
+ data: [string, TransactionReturnDataEncoding];
740
+ };
741
+
714
742
  export type SimulatedTransactionResponse = {
715
743
  err: TransactionError | string | null;
716
744
  logs: Array<string> | null;
717
745
  accounts?: (SimulatedTransactionAccountInfo | null)[] | null;
718
746
  unitsConsumed?: number;
747
+ returnData?: TransactionReturnData | null;
719
748
  };
720
-
721
749
  const SimulatedTransactionResponseStruct = jsonRpcResultAndContext(
722
750
  pick({
723
751
  err: nullable(union([pick({}), string()])),
@@ -738,6 +766,14 @@ const SimulatedTransactionResponseStruct = jsonRpcResultAndContext(
738
766
  ),
739
767
  ),
740
768
  unitsConsumed: optional(number()),
769
+ returnData: optional(
770
+ nullable(
771
+ pick({
772
+ programId: string(),
773
+ data: tuple([string(), literal('base64')]),
774
+ }),
775
+ ),
776
+ ),
741
777
  }),
742
778
  );
743
779
 
@@ -3576,11 +3612,14 @@ export class Connection {
3576
3612
  */
3577
3613
  async getBlock(
3578
3614
  slot: number,
3579
- opts?: {commitment?: Finality},
3615
+ rawConfig?: GetBlockConfig,
3580
3616
  ): Promise<BlockResponse | null> {
3617
+ const {commitment, config} = extractCommitmentFromConfig(rawConfig);
3581
3618
  const args = this._buildArgsAtLeastConfirmed(
3582
3619
  [slot],
3583
- opts && opts.commitment,
3620
+ commitment as Finality,
3621
+ undefined /* encoding */,
3622
+ config,
3584
3623
  );
3585
3624
  const unsafeRes = await this._rpcRequest('getBlock', args);
3586
3625
  const res = create(unsafeRes, GetBlockRpcResult);
@@ -3668,11 +3707,14 @@ export class Connection {
3668
3707
  */
3669
3708
  async getTransaction(
3670
3709
  signature: string,
3671
- opts?: {commitment?: Finality},
3710
+ rawConfig?: GetTransactionConfig,
3672
3711
  ): Promise<TransactionResponse | null> {
3712
+ const {commitment, config} = extractCommitmentFromConfig(rawConfig);
3673
3713
  const args = this._buildArgsAtLeastConfirmed(
3674
3714
  [signature],
3675
- opts && opts.commitment,
3715
+ commitment as Finality,
3716
+ undefined /* encoding */,
3717
+ config,
3676
3718
  );
3677
3719
  const unsafeRes = await this._rpcRequest('getTransaction', args);
3678
3720
  const res = create(unsafeRes, GetTransactionRpcResult);
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './account';
2
+ export * from './address-lookup-table-program';
2
3
  export * from './blockhash';
3
4
  export * from './bpf-loader-deprecated';
4
5
  export * from './bpf-loader';
package/src/layout.ts CHANGED
@@ -135,13 +135,25 @@ export const voteInit = (property: string = 'voteInit') => {
135
135
  };
136
136
 
137
137
  export function getAlloc(type: any, fields: any): number {
138
- let alloc = 0;
139
- type.layout.fields.forEach((item: any) => {
138
+ const getItemAlloc = (item: any): number => {
140
139
  if (item.span >= 0) {
141
- alloc += item.span;
140
+ return item.span;
142
141
  } else if (typeof item.alloc === 'function') {
143
- alloc += item.alloc(fields[item.property]);
142
+ return item.alloc(fields[item.property]);
143
+ } else if ('count' in item && 'elementLayout' in item) {
144
+ const field = fields[item.property];
145
+ if (Array.isArray(field)) {
146
+ return field.length * getItemAlloc(item.elementLayout);
147
+ }
144
148
  }
149
+ // Couldn't determine allocated size of layout
150
+ return 0;
151
+ };
152
+
153
+ let alloc = 0;
154
+ type.layout.fields.forEach((item: any) => {
155
+ alloc += getItemAlloc(item);
145
156
  });
157
+
146
158
  return alloc;
147
159
  }
@@ -0,0 +1,2 @@
1
+ export {default} from 'react-native-url-polyfill';
2
+ export * from 'react-native-url-polyfill';
@@ -1,3 +1,5 @@
1
+ import {URL} from './url-impl';
2
+
1
3
  export function makeWebsocketUrl(endpoint: string) {
2
4
  let url = new URL(endpoint);
3
5
  const useHttps = url.protocol === 'https:';
@@ -0,0 +1,2 @@
1
+ export const URL = globalThis.URL;
2
+ export const URLSearchParams = globalThis.URLSearchParams;