@solana/web3.js 1.47.2 → 1.48.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.2",
3
+ "version": "1.48.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';
@@ -711,13 +712,20 @@ export type SimulatedTransactionAccountInfo = {
711
712
  rentEpoch?: number;
712
713
  };
713
714
 
715
+ export type TransactionReturnDataEncoding = 'base64';
716
+
717
+ export type TransactionReturnData = {
718
+ programId: string;
719
+ data: [string, TransactionReturnDataEncoding];
720
+ };
721
+
714
722
  export type SimulatedTransactionResponse = {
715
723
  err: TransactionError | string | null;
716
724
  logs: Array<string> | null;
717
725
  accounts?: (SimulatedTransactionAccountInfo | null)[] | null;
718
726
  unitsConsumed?: number;
727
+ returnData?: TransactionReturnData | null;
719
728
  };
720
-
721
729
  const SimulatedTransactionResponseStruct = jsonRpcResultAndContext(
722
730
  pick({
723
731
  err: nullable(union([pick({}), string()])),
@@ -738,6 +746,14 @@ const SimulatedTransactionResponseStruct = jsonRpcResultAndContext(
738
746
  ),
739
747
  ),
740
748
  unitsConsumed: optional(number()),
749
+ returnData: optional(
750
+ nullable(
751
+ pick({
752
+ programId: string(),
753
+ data: tuple([string(), literal('base64')]),
754
+ }),
755
+ ),
756
+ ),
741
757
  }),
742
758
  );
743
759
 
@@ -3051,15 +3067,6 @@ export class Connection {
3051
3067
  }
3052
3068
  });
3053
3069
 
3054
- const checkBlockHeight = async () => {
3055
- try {
3056
- const blockHeight = await this.getBlockHeight(commitment);
3057
- return blockHeight;
3058
- } catch (_e) {
3059
- return -1;
3060
- }
3061
- };
3062
-
3063
3070
  const expiryPromise = new Promise<
3064
3071
  | {__type: TransactionStatus.BLOCKHEIGHT_EXCEEDED}
3065
3072
  | {__type: TransactionStatus.TIMED_OUT; timeoutMs: number}
@@ -3088,6 +3095,14 @@ export class Connection {
3088
3095
  } else {
3089
3096
  let config =
3090
3097
  strategy as BlockheightBasedTransactionConfirmationStrategy;
3098
+ const checkBlockHeight = async () => {
3099
+ try {
3100
+ const blockHeight = await this.getBlockHeight(commitment);
3101
+ return blockHeight;
3102
+ } catch (_e) {
3103
+ return -1;
3104
+ }
3105
+ };
3091
3106
  (async () => {
3092
3107
  let currentBlockHeight = await checkBlockHeight();
3093
3108
  if (done) return;
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
  }
@@ -258,17 +258,25 @@ export class Transaction {
258
258
  ) {
259
259
  if (!opts) {
260
260
  return;
261
- } else if (
262
- Object.prototype.hasOwnProperty.call(opts, 'lastValidBlockHeight')
263
- ) {
264
- const newOpts = opts as TransactionBlockhashCtor;
265
- Object.assign(this, newOpts);
266
- this.recentBlockhash = newOpts.blockhash;
267
- this.lastValidBlockHeight = newOpts.lastValidBlockHeight;
261
+ }
262
+ if (opts.feePayer) {
263
+ this.feePayer = opts.feePayer;
264
+ }
265
+ if (opts.signatures) {
266
+ this.signatures = opts.signatures;
267
+ }
268
+ if (Object.prototype.hasOwnProperty.call(opts, 'lastValidBlockHeight')) {
269
+ const {blockhash, lastValidBlockHeight} =
270
+ opts as TransactionBlockhashCtor;
271
+ this.recentBlockhash = blockhash;
272
+ this.lastValidBlockHeight = lastValidBlockHeight;
268
273
  } else {
269
- const oldOpts = opts as TransactionCtorFields_DEPRECATED;
270
- Object.assign(this, oldOpts);
271
- this.recentBlockhash = oldOpts.recentBlockhash;
274
+ const {recentBlockhash, nonceInfo} =
275
+ opts as TransactionCtorFields_DEPRECATED;
276
+ if (nonceInfo) {
277
+ this.nonceInfo = nonceInfo;
278
+ }
279
+ this.recentBlockhash = recentBlockhash;
272
280
  }
273
281
  }
274
282
 
@@ -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;