@solana/web3.js 1.56.0 → 1.57.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/lib/index.cjs.js CHANGED
@@ -149,12 +149,14 @@ const PUBLIC_KEY_LENGTH = 32;
149
149
 
150
150
  function isPublicKeyData(value) {
151
151
  return value._bn !== undefined;
152
- }
152
+ } // local counter used by PublicKey.unique()
153
+
154
+
155
+ let uniquePublicKeyCounter = 1;
153
156
  /**
154
157
  * A public key
155
158
  */
156
159
 
157
-
158
160
  class PublicKey extends Struct {
159
161
  /** @internal */
160
162
 
@@ -187,6 +189,16 @@ class PublicKey extends Struct {
187
189
  }
188
190
  }
189
191
  }
192
+ /**
193
+ * Returns a unique PublicKey for tests and benchmarks using acounter
194
+ */
195
+
196
+
197
+ static unique() {
198
+ const key = new PublicKey(uniquePublicKeyCounter);
199
+ uniquePublicKeyCounter += 1;
200
+ return new PublicKey(key.toBuffer());
201
+ }
190
202
  /**
191
203
  * Default public key value. (All zeros)
192
204
  */
@@ -443,6 +455,71 @@ Object.defineProperty(TransactionExpiredTimeoutError.prototype, 'name', {
443
455
  value: 'TransactionExpiredTimeoutError'
444
456
  });
445
457
 
458
+ class MessageAccountKeys {
459
+ constructor(staticAccountKeys, accountKeysFromLookups) {
460
+ this.staticAccountKeys = void 0;
461
+ this.accountKeysFromLookups = void 0;
462
+ this.staticAccountKeys = staticAccountKeys;
463
+ this.accountKeysFromLookups = accountKeysFromLookups;
464
+ }
465
+
466
+ keySegments() {
467
+ const keySegments = [this.staticAccountKeys];
468
+
469
+ if (this.accountKeysFromLookups) {
470
+ keySegments.push(this.accountKeysFromLookups.writable);
471
+ keySegments.push(this.accountKeysFromLookups.readonly);
472
+ }
473
+
474
+ return keySegments;
475
+ }
476
+
477
+ get(index) {
478
+ for (const keySegment of this.keySegments()) {
479
+ if (index < keySegment.length) {
480
+ return keySegment[index];
481
+ } else {
482
+ index -= keySegment.length;
483
+ }
484
+ }
485
+
486
+ return;
487
+ }
488
+
489
+ get length() {
490
+ return this.keySegments().flat().length;
491
+ }
492
+
493
+ compileInstructions(instructions) {
494
+ // Bail early if any account indexes would overflow a u8
495
+ const U8_MAX = 255;
496
+
497
+ if (this.length > U8_MAX + 1) {
498
+ throw new Error('Account index overflow encountered during compilation');
499
+ }
500
+
501
+ const keyIndexMap = new Map();
502
+ this.keySegments().flat().forEach((key, index) => {
503
+ keyIndexMap.set(key.toBase58(), index);
504
+ });
505
+
506
+ const findKeyIndex = key => {
507
+ const keyIndex = keyIndexMap.get(key.toBase58());
508
+ if (keyIndex === undefined) throw new Error('Encountered an unknown instruction account key during compilation');
509
+ return keyIndex;
510
+ };
511
+
512
+ return instructions.map(instruction => {
513
+ return {
514
+ programIdIndex: findKeyIndex(instruction.programId),
515
+ accountKeyIndexes: instruction.keys.map(meta => findKeyIndex(meta.pubkey)),
516
+ data: instruction.data
517
+ };
518
+ });
519
+ }
520
+
521
+ }
522
+
446
523
  /**
447
524
  * Layout for a public key
448
525
  */
@@ -739,6 +816,115 @@ function assert (condition, message) {
739
816
  }
740
817
  }
741
818
 
819
+ class CompiledKeys {
820
+ constructor(payer, keyMetaMap) {
821
+ this.payer = void 0;
822
+ this.keyMetaMap = void 0;
823
+ this.payer = payer;
824
+ this.keyMetaMap = keyMetaMap;
825
+ }
826
+
827
+ static compile(instructions, payer) {
828
+ const keyMetaMap = new Map();
829
+
830
+ const getOrInsertDefault = pubkey => {
831
+ const address = pubkey.toBase58();
832
+ let keyMeta = keyMetaMap.get(address);
833
+
834
+ if (keyMeta === undefined) {
835
+ keyMeta = {
836
+ isSigner: false,
837
+ isWritable: false,
838
+ isInvoked: false
839
+ };
840
+ keyMetaMap.set(address, keyMeta);
841
+ }
842
+
843
+ return keyMeta;
844
+ };
845
+
846
+ const payerKeyMeta = getOrInsertDefault(payer);
847
+ payerKeyMeta.isSigner = true;
848
+ payerKeyMeta.isWritable = true;
849
+
850
+ for (const ix of instructions) {
851
+ getOrInsertDefault(ix.programId).isInvoked = true;
852
+
853
+ for (const accountMeta of ix.keys) {
854
+ const keyMeta = getOrInsertDefault(accountMeta.pubkey);
855
+ keyMeta.isSigner || (keyMeta.isSigner = accountMeta.isSigner);
856
+ keyMeta.isWritable || (keyMeta.isWritable = accountMeta.isWritable);
857
+ }
858
+ }
859
+
860
+ return new CompiledKeys(payer, keyMetaMap);
861
+ }
862
+
863
+ getMessageComponents() {
864
+ const mapEntries = [...this.keyMetaMap.entries()];
865
+ assert(mapEntries.length <= 256, 'Max static account keys length exceeded');
866
+ const writableSigners = mapEntries.filter(([, meta]) => meta.isSigner && meta.isWritable);
867
+ const readonlySigners = mapEntries.filter(([, meta]) => meta.isSigner && !meta.isWritable);
868
+ const writableNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && meta.isWritable);
869
+ const readonlyNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && !meta.isWritable);
870
+ const header = {
871
+ numRequiredSignatures: writableSigners.length + readonlySigners.length,
872
+ numReadonlySignedAccounts: readonlySigners.length,
873
+ numReadonlyUnsignedAccounts: readonlyNonSigners.length
874
+ }; // sanity checks
875
+
876
+ {
877
+ assert(writableSigners.length > 0, 'Expected at least one writable signer key');
878
+ const [payerAddress] = writableSigners[0];
879
+ assert(payerAddress === this.payer.toBase58(), 'Expected first writable signer key to be the fee payer');
880
+ }
881
+ const staticAccountKeys = [...writableSigners.map(([address]) => new PublicKey(address)), ...readonlySigners.map(([address]) => new PublicKey(address)), ...writableNonSigners.map(([address]) => new PublicKey(address)), ...readonlyNonSigners.map(([address]) => new PublicKey(address))];
882
+ return [header, staticAccountKeys];
883
+ }
884
+
885
+ extractTableLookup(lookupTable) {
886
+ const [writableIndexes, drainedWritableKeys] = this.drainKeysFoundInLookupTable(lookupTable.state.addresses, keyMeta => !keyMeta.isSigner && !keyMeta.isInvoked && keyMeta.isWritable);
887
+ const [readonlyIndexes, drainedReadonlyKeys] = this.drainKeysFoundInLookupTable(lookupTable.state.addresses, keyMeta => !keyMeta.isSigner && !keyMeta.isInvoked && !keyMeta.isWritable); // Don't extract lookup if no keys were found
888
+
889
+ if (writableIndexes.length === 0 && readonlyIndexes.length === 0) {
890
+ return;
891
+ }
892
+
893
+ return [{
894
+ accountKey: lookupTable.key,
895
+ writableIndexes,
896
+ readonlyIndexes
897
+ }, {
898
+ writable: drainedWritableKeys,
899
+ readonly: drainedReadonlyKeys
900
+ }];
901
+ }
902
+ /** @internal */
903
+
904
+
905
+ drainKeysFoundInLookupTable(lookupTableEntries, keyMetaFilter) {
906
+ const lookupTableIndexes = new Array();
907
+ const drainedKeys = new Array();
908
+
909
+ for (const [address, keyMeta] of this.keyMetaMap.entries()) {
910
+ if (keyMetaFilter(keyMeta)) {
911
+ const key = new PublicKey(address);
912
+ const lookupTableIndex = lookupTableEntries.findIndex(entry => entry.equals(key));
913
+
914
+ if (lookupTableIndex >= 0) {
915
+ assert(lookupTableIndex < 256, 'Max lookup table index exceeded');
916
+ lookupTableIndexes.push(lookupTableIndex);
917
+ drainedKeys.push(key);
918
+ this.keyMetaMap.delete(address);
919
+ }
920
+ }
921
+ }
922
+
923
+ return [lookupTableIndexes, drainedKeys];
924
+ }
925
+
926
+ }
927
+
742
928
  /**
743
929
  * Message constructor arguments
744
930
  */
@@ -761,6 +947,41 @@ class MessageV0 {
761
947
  return 0;
762
948
  }
763
949
 
950
+ static compile(args) {
951
+ const compiledKeys = CompiledKeys.compile(args.instructions, args.payerKey);
952
+ const addressTableLookups = new Array();
953
+ const accountKeysFromLookups = {
954
+ writable: new Array(),
955
+ readonly: new Array()
956
+ };
957
+ const lookupTableAccounts = args.addressLookupTableAccounts || [];
958
+
959
+ for (const lookupTable of lookupTableAccounts) {
960
+ const extractResult = compiledKeys.extractTableLookup(lookupTable);
961
+
962
+ if (extractResult !== undefined) {
963
+ const [addressTableLookup, {
964
+ writable,
965
+ readonly
966
+ }] = extractResult;
967
+ addressTableLookups.push(addressTableLookup);
968
+ accountKeysFromLookups.writable.push(...writable);
969
+ accountKeysFromLookups.readonly.push(...readonly);
970
+ }
971
+ }
972
+
973
+ const [header, staticAccountKeys] = compiledKeys.getMessageComponents();
974
+ const accountKeys = new MessageAccountKeys(staticAccountKeys, accountKeysFromLookups);
975
+ const compiledInstructions = accountKeys.compileInstructions(args.instructions);
976
+ return new MessageV0({
977
+ header,
978
+ staticAccountKeys,
979
+ recentBlockhash: args.recentBlockhash,
980
+ compiledInstructions,
981
+ addressTableLookups
982
+ });
983
+ }
984
+
764
985
  serialize() {
765
986
  const encodedStaticAccountKeysLength = Array();
766
987
  encodeLength(encodedStaticAccountKeysLength, this.staticAccountKeys.length);
@@ -3979,7 +4200,8 @@ const ConfirmedTransactionMetaResult = superstruct.type({
3979
4200
  logMessages: superstruct.optional(superstruct.nullable(superstruct.array(superstruct.string()))),
3980
4201
  preTokenBalances: superstruct.optional(superstruct.nullable(superstruct.array(TokenBalanceResult))),
3981
4202
  postTokenBalances: superstruct.optional(superstruct.nullable(superstruct.array(TokenBalanceResult))),
3982
- loadedAddresses: superstruct.optional(LoadedAddressesResult)
4203
+ loadedAddresses: superstruct.optional(LoadedAddressesResult),
4204
+ computeUnitsConsumed: superstruct.optional(superstruct.number())
3983
4205
  });
3984
4206
  /**
3985
4207
  * @internal
@@ -3997,7 +4219,8 @@ const ParsedConfirmedTransactionMetaResult = superstruct.type({
3997
4219
  logMessages: superstruct.optional(superstruct.nullable(superstruct.array(superstruct.string()))),
3998
4220
  preTokenBalances: superstruct.optional(superstruct.nullable(superstruct.array(TokenBalanceResult))),
3999
4221
  postTokenBalances: superstruct.optional(superstruct.nullable(superstruct.array(TokenBalanceResult))),
4000
- loadedAddresses: superstruct.optional(LoadedAddressesResult)
4222
+ loadedAddresses: superstruct.optional(LoadedAddressesResult),
4223
+ computeUnitsConsumed: superstruct.optional(superstruct.number())
4001
4224
  });
4002
4225
  const TransactionVersionStruct = superstruct.union([superstruct.literal(0), superstruct.literal('legacy')]);
4003
4226
  /**
@@ -9171,6 +9394,7 @@ exports.Loader = Loader;
9171
9394
  exports.Lockup = Lockup;
9172
9395
  exports.MAX_SEED_LENGTH = MAX_SEED_LENGTH;
9173
9396
  exports.Message = Message;
9397
+ exports.MessageAccountKeys = MessageAccountKeys;
9174
9398
  exports.MessageV0 = MessageV0;
9175
9399
  exports.NONCE_ACCOUNT_LENGTH = NONCE_ACCOUNT_LENGTH;
9176
9400
  exports.NonceAccount = NonceAccount;