@solana/web3.js 1.57.0 → 1.59.1
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.browser.cjs.js +460 -121
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +460 -121
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +460 -121
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +105 -1
- package/lib/index.esm.js +460 -121
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +726 -831
- package/lib/index.iife.js.map +1 -1
- package/lib/index.iife.min.js +5 -13
- package/lib/index.iife.min.js.map +1 -1
- package/lib/index.native.js +460 -121
- package/lib/index.native.js.map +1 -1
- package/package.json +1 -2
- package/src/connection.ts +106 -2
- package/src/layout.ts +22 -0
- package/src/message/legacy.ts +34 -2
- package/src/message/v0.ts +90 -0
- package/src/programs/secp256k1.ts +5 -7
- package/src/programs/vote.ts +109 -2
- package/src/transaction/index.ts +1 -0
- package/src/transaction/message.ts +138 -0
package/lib/index.native.js
CHANGED
|
@@ -14,7 +14,7 @@ var bigintBuffer = require('bigint-buffer');
|
|
|
14
14
|
var superstruct = require('superstruct');
|
|
15
15
|
var rpcWebsockets = require('rpc-websockets');
|
|
16
16
|
var RpcClient = require('jayson/lib/client/browser');
|
|
17
|
-
var sha3 = require('
|
|
17
|
+
var sha3 = require('@noble/hashes/sha3');
|
|
18
18
|
var hmac = require('@noble/hashes/hmac');
|
|
19
19
|
var secp256k1 = require('@noble/secp256k1');
|
|
20
20
|
|
|
@@ -43,7 +43,6 @@ var BN__default = /*#__PURE__*/_interopDefaultLegacy(BN);
|
|
|
43
43
|
var bs58__default = /*#__PURE__*/_interopDefaultLegacy(bs58);
|
|
44
44
|
var BufferLayout__namespace = /*#__PURE__*/_interopNamespace(BufferLayout);
|
|
45
45
|
var RpcClient__default = /*#__PURE__*/_interopDefaultLegacy(RpcClient);
|
|
46
|
-
var sha3__default = /*#__PURE__*/_interopDefaultLegacy(sha3);
|
|
47
46
|
var secp256k1__namespace = /*#__PURE__*/_interopNamespace(secp256k1);
|
|
48
47
|
|
|
49
48
|
/**
|
|
@@ -517,7 +516,6 @@ class MessageAccountKeys {
|
|
|
517
516
|
/**
|
|
518
517
|
* Layout for a public key
|
|
519
518
|
*/
|
|
520
|
-
|
|
521
519
|
const publicKey = (property = 'publicKey') => {
|
|
522
520
|
return BufferLayout__namespace.blob(32, property);
|
|
523
521
|
};
|
|
@@ -581,6 +579,13 @@ const lockup = (property = 'lockup') => {
|
|
|
581
579
|
const voteInit = (property = 'voteInit') => {
|
|
582
580
|
return BufferLayout__namespace.struct([publicKey('nodePubkey'), publicKey('authorizedVoter'), publicKey('authorizedWithdrawer'), BufferLayout__namespace.u8('commission')], property);
|
|
583
581
|
};
|
|
582
|
+
/**
|
|
583
|
+
* Layout for a VoteAuthorizeWithSeedArgs object
|
|
584
|
+
*/
|
|
585
|
+
|
|
586
|
+
const voteAuthorizeWithSeedArgs = (property = 'voteAuthorizeWithSeedArgs') => {
|
|
587
|
+
return BufferLayout__namespace.struct([BufferLayout__namespace.u32('voteAuthorizationType'), publicKey('currentAuthorityDerivedKeyOwnerPubkey'), rustString('currentAuthorityDerivedKeySeed'), publicKey('newAuthorized')], property);
|
|
588
|
+
};
|
|
584
589
|
function getAlloc(type, fields) {
|
|
585
590
|
const getItemAlloc = item => {
|
|
586
591
|
if (item.span >= 0) {
|
|
@@ -593,6 +598,11 @@ function getAlloc(type, fields) {
|
|
|
593
598
|
if (Array.isArray(field)) {
|
|
594
599
|
return field.length * getItemAlloc(item.elementLayout);
|
|
595
600
|
}
|
|
601
|
+
} else if ('fields' in item) {
|
|
602
|
+
// This is a `Structure` whose size needs to be recursively measured.
|
|
603
|
+
return getAlloc({
|
|
604
|
+
layout: item
|
|
605
|
+
}, fields[item.property]);
|
|
596
606
|
} // Couldn't determine allocated size of layout
|
|
597
607
|
|
|
598
608
|
|
|
@@ -639,6 +649,129 @@ function encodeLength(bytes, len) {
|
|
|
639
649
|
}
|
|
640
650
|
}
|
|
641
651
|
|
|
652
|
+
function assert (condition, message) {
|
|
653
|
+
if (!condition) {
|
|
654
|
+
throw new Error(message || 'Assertion failed');
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
class CompiledKeys {
|
|
659
|
+
constructor(payer, keyMetaMap) {
|
|
660
|
+
this.payer = void 0;
|
|
661
|
+
this.keyMetaMap = void 0;
|
|
662
|
+
this.payer = payer;
|
|
663
|
+
this.keyMetaMap = keyMetaMap;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
static compile(instructions, payer) {
|
|
667
|
+
const keyMetaMap = new Map();
|
|
668
|
+
|
|
669
|
+
const getOrInsertDefault = pubkey => {
|
|
670
|
+
const address = pubkey.toBase58();
|
|
671
|
+
let keyMeta = keyMetaMap.get(address);
|
|
672
|
+
|
|
673
|
+
if (keyMeta === undefined) {
|
|
674
|
+
keyMeta = {
|
|
675
|
+
isSigner: false,
|
|
676
|
+
isWritable: false,
|
|
677
|
+
isInvoked: false
|
|
678
|
+
};
|
|
679
|
+
keyMetaMap.set(address, keyMeta);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
return keyMeta;
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
const payerKeyMeta = getOrInsertDefault(payer);
|
|
686
|
+
payerKeyMeta.isSigner = true;
|
|
687
|
+
payerKeyMeta.isWritable = true;
|
|
688
|
+
|
|
689
|
+
for (const ix of instructions) {
|
|
690
|
+
getOrInsertDefault(ix.programId).isInvoked = true;
|
|
691
|
+
|
|
692
|
+
for (const accountMeta of ix.keys) {
|
|
693
|
+
const keyMeta = getOrInsertDefault(accountMeta.pubkey);
|
|
694
|
+
keyMeta.isSigner || (keyMeta.isSigner = accountMeta.isSigner);
|
|
695
|
+
keyMeta.isWritable || (keyMeta.isWritable = accountMeta.isWritable);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
return new CompiledKeys(payer, keyMetaMap);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
getMessageComponents() {
|
|
703
|
+
const mapEntries = [...this.keyMetaMap.entries()];
|
|
704
|
+
assert(mapEntries.length <= 256, 'Max static account keys length exceeded');
|
|
705
|
+
const writableSigners = mapEntries.filter(([, meta]) => meta.isSigner && meta.isWritable);
|
|
706
|
+
const readonlySigners = mapEntries.filter(([, meta]) => meta.isSigner && !meta.isWritable);
|
|
707
|
+
const writableNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && meta.isWritable);
|
|
708
|
+
const readonlyNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && !meta.isWritable);
|
|
709
|
+
const header = {
|
|
710
|
+
numRequiredSignatures: writableSigners.length + readonlySigners.length,
|
|
711
|
+
numReadonlySignedAccounts: readonlySigners.length,
|
|
712
|
+
numReadonlyUnsignedAccounts: readonlyNonSigners.length
|
|
713
|
+
}; // sanity checks
|
|
714
|
+
|
|
715
|
+
{
|
|
716
|
+
assert(writableSigners.length > 0, 'Expected at least one writable signer key');
|
|
717
|
+
const [payerAddress] = writableSigners[0];
|
|
718
|
+
assert(payerAddress === this.payer.toBase58(), 'Expected first writable signer key to be the fee payer');
|
|
719
|
+
}
|
|
720
|
+
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))];
|
|
721
|
+
return [header, staticAccountKeys];
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
extractTableLookup(lookupTable) {
|
|
725
|
+
const [writableIndexes, drainedWritableKeys] = this.drainKeysFoundInLookupTable(lookupTable.state.addresses, keyMeta => !keyMeta.isSigner && !keyMeta.isInvoked && keyMeta.isWritable);
|
|
726
|
+
const [readonlyIndexes, drainedReadonlyKeys] = this.drainKeysFoundInLookupTable(lookupTable.state.addresses, keyMeta => !keyMeta.isSigner && !keyMeta.isInvoked && !keyMeta.isWritable); // Don't extract lookup if no keys were found
|
|
727
|
+
|
|
728
|
+
if (writableIndexes.length === 0 && readonlyIndexes.length === 0) {
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
return [{
|
|
733
|
+
accountKey: lookupTable.key,
|
|
734
|
+
writableIndexes,
|
|
735
|
+
readonlyIndexes
|
|
736
|
+
}, {
|
|
737
|
+
writable: drainedWritableKeys,
|
|
738
|
+
readonly: drainedReadonlyKeys
|
|
739
|
+
}];
|
|
740
|
+
}
|
|
741
|
+
/** @internal */
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
drainKeysFoundInLookupTable(lookupTableEntries, keyMetaFilter) {
|
|
745
|
+
const lookupTableIndexes = new Array();
|
|
746
|
+
const drainedKeys = new Array();
|
|
747
|
+
|
|
748
|
+
for (const [address, keyMeta] of this.keyMetaMap.entries()) {
|
|
749
|
+
if (keyMetaFilter(keyMeta)) {
|
|
750
|
+
const key = new PublicKey(address);
|
|
751
|
+
const lookupTableIndex = lookupTableEntries.findIndex(entry => entry.equals(key));
|
|
752
|
+
|
|
753
|
+
if (lookupTableIndex >= 0) {
|
|
754
|
+
assert(lookupTableIndex < 256, 'Max lookup table index exceeded');
|
|
755
|
+
lookupTableIndexes.push(lookupTableIndex);
|
|
756
|
+
drainedKeys.push(key);
|
|
757
|
+
this.keyMetaMap.delete(address);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
return [lookupTableIndexes, drainedKeys];
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* An instruction to execute by a program
|
|
769
|
+
*
|
|
770
|
+
* @property {number} programIdIndex
|
|
771
|
+
* @property {number[]} accounts
|
|
772
|
+
* @property {string} data
|
|
773
|
+
*/
|
|
774
|
+
|
|
642
775
|
/**
|
|
643
776
|
* List of instructions to be processed atomically
|
|
644
777
|
*/
|
|
@@ -676,6 +809,27 @@ class Message {
|
|
|
676
809
|
return [];
|
|
677
810
|
}
|
|
678
811
|
|
|
812
|
+
getAccountKeys() {
|
|
813
|
+
return new MessageAccountKeys(this.staticAccountKeys);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
static compile(args) {
|
|
817
|
+
const compiledKeys = CompiledKeys.compile(args.instructions, args.payerKey);
|
|
818
|
+
const [header, staticAccountKeys] = compiledKeys.getMessageComponents();
|
|
819
|
+
const accountKeys = new MessageAccountKeys(staticAccountKeys);
|
|
820
|
+
const instructions = accountKeys.compileInstructions(args.instructions).map(ix => ({
|
|
821
|
+
programIdIndex: ix.programIdIndex,
|
|
822
|
+
accounts: ix.accountKeyIndexes,
|
|
823
|
+
data: bs58__default["default"].encode(ix.data)
|
|
824
|
+
}));
|
|
825
|
+
return new Message({
|
|
826
|
+
header,
|
|
827
|
+
accountKeys: staticAccountKeys,
|
|
828
|
+
recentBlockhash: args.recentBlockhash,
|
|
829
|
+
instructions
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
|
|
679
833
|
isAccountSigner(index) {
|
|
680
834
|
return index < this.header.numRequiredSignatures;
|
|
681
835
|
}
|
|
@@ -765,7 +919,7 @@ class Message {
|
|
|
765
919
|
for (let i = 0; i < accountCount; i++) {
|
|
766
920
|
const account = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
767
921
|
byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
|
|
768
|
-
accountKeys.push(
|
|
922
|
+
accountKeys.push(new PublicKey(buffer.Buffer.from(account)));
|
|
769
923
|
}
|
|
770
924
|
|
|
771
925
|
const recentBlockhash = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
@@ -804,141 +958,87 @@ class Message {
|
|
|
804
958
|
|
|
805
959
|
}
|
|
806
960
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
}
|
|
811
|
-
}
|
|
961
|
+
/**
|
|
962
|
+
* Message constructor arguments
|
|
963
|
+
*/
|
|
812
964
|
|
|
813
|
-
class
|
|
814
|
-
constructor(
|
|
815
|
-
this.
|
|
816
|
-
this.
|
|
817
|
-
this.
|
|
818
|
-
this.
|
|
965
|
+
class MessageV0 {
|
|
966
|
+
constructor(args) {
|
|
967
|
+
this.header = void 0;
|
|
968
|
+
this.staticAccountKeys = void 0;
|
|
969
|
+
this.recentBlockhash = void 0;
|
|
970
|
+
this.compiledInstructions = void 0;
|
|
971
|
+
this.addressTableLookups = void 0;
|
|
972
|
+
this.header = args.header;
|
|
973
|
+
this.staticAccountKeys = args.staticAccountKeys;
|
|
974
|
+
this.recentBlockhash = args.recentBlockhash;
|
|
975
|
+
this.compiledInstructions = args.compiledInstructions;
|
|
976
|
+
this.addressTableLookups = args.addressTableLookups;
|
|
819
977
|
}
|
|
820
978
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
const getOrInsertDefault = pubkey => {
|
|
825
|
-
const address = pubkey.toBase58();
|
|
826
|
-
let keyMeta = keyMetaMap.get(address);
|
|
827
|
-
|
|
828
|
-
if (keyMeta === undefined) {
|
|
829
|
-
keyMeta = {
|
|
830
|
-
isSigner: false,
|
|
831
|
-
isWritable: false,
|
|
832
|
-
isInvoked: false
|
|
833
|
-
};
|
|
834
|
-
keyMetaMap.set(address, keyMeta);
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
return keyMeta;
|
|
838
|
-
};
|
|
839
|
-
|
|
840
|
-
const payerKeyMeta = getOrInsertDefault(payer);
|
|
841
|
-
payerKeyMeta.isSigner = true;
|
|
842
|
-
payerKeyMeta.isWritable = true;
|
|
979
|
+
get version() {
|
|
980
|
+
return 0;
|
|
981
|
+
}
|
|
843
982
|
|
|
844
|
-
|
|
845
|
-
|
|
983
|
+
get numAccountKeysFromLookups() {
|
|
984
|
+
let count = 0;
|
|
846
985
|
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
keyMeta.isSigner || (keyMeta.isSigner = accountMeta.isSigner);
|
|
850
|
-
keyMeta.isWritable || (keyMeta.isWritable = accountMeta.isWritable);
|
|
851
|
-
}
|
|
986
|
+
for (const lookup of this.addressTableLookups) {
|
|
987
|
+
count += lookup.readonlyIndexes.length + lookup.writableIndexes.length;
|
|
852
988
|
}
|
|
853
989
|
|
|
854
|
-
return
|
|
990
|
+
return count;
|
|
855
991
|
}
|
|
856
992
|
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
assert(mapEntries.length <= 256, 'Max static account keys length exceeded');
|
|
860
|
-
const writableSigners = mapEntries.filter(([, meta]) => meta.isSigner && meta.isWritable);
|
|
861
|
-
const readonlySigners = mapEntries.filter(([, meta]) => meta.isSigner && !meta.isWritable);
|
|
862
|
-
const writableNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && meta.isWritable);
|
|
863
|
-
const readonlyNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && !meta.isWritable);
|
|
864
|
-
const header = {
|
|
865
|
-
numRequiredSignatures: writableSigners.length + readonlySigners.length,
|
|
866
|
-
numReadonlySignedAccounts: readonlySigners.length,
|
|
867
|
-
numReadonlyUnsignedAccounts: readonlyNonSigners.length
|
|
868
|
-
}; // sanity checks
|
|
869
|
-
|
|
870
|
-
{
|
|
871
|
-
assert(writableSigners.length > 0, 'Expected at least one writable signer key');
|
|
872
|
-
const [payerAddress] = writableSigners[0];
|
|
873
|
-
assert(payerAddress === this.payer.toBase58(), 'Expected first writable signer key to be the fee payer');
|
|
874
|
-
}
|
|
875
|
-
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))];
|
|
876
|
-
return [header, staticAccountKeys];
|
|
877
|
-
}
|
|
993
|
+
getAccountKeys(args) {
|
|
994
|
+
let accountKeysFromLookups;
|
|
878
995
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
996
|
+
if (args && 'accountKeysFromLookups' in args) {
|
|
997
|
+
if (this.numAccountKeysFromLookups != args.accountKeysFromLookups.writable.length + args.accountKeysFromLookups.readonly.length) {
|
|
998
|
+
throw new Error('Failed to get account keys because of a mismatch in the number of account keys from lookups');
|
|
999
|
+
}
|
|
882
1000
|
|
|
883
|
-
|
|
884
|
-
|
|
1001
|
+
accountKeysFromLookups = args.accountKeysFromLookups;
|
|
1002
|
+
} else if (args && 'addressLookupTableAccounts' in args) {
|
|
1003
|
+
accountKeysFromLookups = this.resolveAddressTableLookups(args.addressLookupTableAccounts);
|
|
1004
|
+
} else if (this.addressTableLookups.length > 0) {
|
|
1005
|
+
throw new Error('Failed to get account keys because address table lookups were not resolved');
|
|
885
1006
|
}
|
|
886
1007
|
|
|
887
|
-
return
|
|
888
|
-
accountKey: lookupTable.key,
|
|
889
|
-
writableIndexes,
|
|
890
|
-
readonlyIndexes
|
|
891
|
-
}, {
|
|
892
|
-
writable: drainedWritableKeys,
|
|
893
|
-
readonly: drainedReadonlyKeys
|
|
894
|
-
}];
|
|
1008
|
+
return new MessageAccountKeys(this.staticAccountKeys, accountKeysFromLookups);
|
|
895
1009
|
}
|
|
896
|
-
/** @internal */
|
|
897
1010
|
|
|
1011
|
+
resolveAddressTableLookups(addressLookupTableAccounts) {
|
|
1012
|
+
const accountKeysFromLookups = {
|
|
1013
|
+
writable: [],
|
|
1014
|
+
readonly: []
|
|
1015
|
+
};
|
|
898
1016
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
const drainedKeys = new Array();
|
|
1017
|
+
for (const tableLookup of this.addressTableLookups) {
|
|
1018
|
+
const tableAccount = addressLookupTableAccounts.find(account => account.key.equals(tableLookup.accountKey));
|
|
902
1019
|
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
const lookupTableIndex = lookupTableEntries.findIndex(entry => entry.equals(key));
|
|
1020
|
+
if (!tableAccount) {
|
|
1021
|
+
throw new Error(`Failed to find address lookup table account for table key ${tableLookup.accountKey.toBase58()}`);
|
|
1022
|
+
}
|
|
907
1023
|
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1024
|
+
for (const index of tableLookup.writableIndexes) {
|
|
1025
|
+
if (index < tableAccount.state.addresses.length) {
|
|
1026
|
+
accountKeysFromLookups.writable.push(tableAccount.state.addresses[index]);
|
|
1027
|
+
} else {
|
|
1028
|
+
throw new Error(`Failed to find address for index ${index} in address lookup table ${tableLookup.accountKey.toBase58()}`);
|
|
913
1029
|
}
|
|
914
1030
|
}
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
return [lookupTableIndexes, drainedKeys];
|
|
918
|
-
}
|
|
919
1031
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
this.header = void 0;
|
|
929
|
-
this.staticAccountKeys = void 0;
|
|
930
|
-
this.recentBlockhash = void 0;
|
|
931
|
-
this.compiledInstructions = void 0;
|
|
932
|
-
this.addressTableLookups = void 0;
|
|
933
|
-
this.header = args.header;
|
|
934
|
-
this.staticAccountKeys = args.staticAccountKeys;
|
|
935
|
-
this.recentBlockhash = args.recentBlockhash;
|
|
936
|
-
this.compiledInstructions = args.compiledInstructions;
|
|
937
|
-
this.addressTableLookups = args.addressTableLookups;
|
|
938
|
-
}
|
|
1032
|
+
for (const index of tableLookup.readonlyIndexes) {
|
|
1033
|
+
if (index < tableAccount.state.addresses.length) {
|
|
1034
|
+
accountKeysFromLookups.readonly.push(tableAccount.state.addresses[index]);
|
|
1035
|
+
} else {
|
|
1036
|
+
throw new Error(`Failed to find address for index ${index} in address lookup table ${tableLookup.accountKey.toBase58()}`);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
939
1040
|
|
|
940
|
-
|
|
941
|
-
return 0;
|
|
1041
|
+
return accountKeysFromLookups;
|
|
942
1042
|
}
|
|
943
1043
|
|
|
944
1044
|
static compile(args) {
|
|
@@ -1870,6 +1970,108 @@ class Transaction {
|
|
|
1870
1970
|
|
|
1871
1971
|
}
|
|
1872
1972
|
|
|
1973
|
+
class TransactionMessage {
|
|
1974
|
+
constructor(args) {
|
|
1975
|
+
this.payerKey = void 0;
|
|
1976
|
+
this.instructions = void 0;
|
|
1977
|
+
this.recentBlockhash = void 0;
|
|
1978
|
+
this.payerKey = args.payerKey;
|
|
1979
|
+
this.instructions = args.instructions;
|
|
1980
|
+
this.recentBlockhash = args.recentBlockhash;
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
static decompile(message, args) {
|
|
1984
|
+
const {
|
|
1985
|
+
header,
|
|
1986
|
+
compiledInstructions,
|
|
1987
|
+
recentBlockhash
|
|
1988
|
+
} = message;
|
|
1989
|
+
const {
|
|
1990
|
+
numRequiredSignatures,
|
|
1991
|
+
numReadonlySignedAccounts,
|
|
1992
|
+
numReadonlyUnsignedAccounts
|
|
1993
|
+
} = header;
|
|
1994
|
+
const numWritableSignedAccounts = numRequiredSignatures - numReadonlySignedAccounts;
|
|
1995
|
+
assert(numWritableSignedAccounts > 0, 'Message header is invalid');
|
|
1996
|
+
const numWritableUnsignedAccounts = message.staticAccountKeys.length - numReadonlyUnsignedAccounts;
|
|
1997
|
+
assert(numWritableUnsignedAccounts >= 0, 'Message header is invalid');
|
|
1998
|
+
const accountKeys = message.getAccountKeys(args);
|
|
1999
|
+
const payerKey = accountKeys.get(0);
|
|
2000
|
+
|
|
2001
|
+
if (payerKey === undefined) {
|
|
2002
|
+
throw new Error('Failed to decompile message because no account keys were found');
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
const instructions = [];
|
|
2006
|
+
|
|
2007
|
+
for (const compiledIx of compiledInstructions) {
|
|
2008
|
+
const keys = [];
|
|
2009
|
+
|
|
2010
|
+
for (const keyIndex of compiledIx.accountKeyIndexes) {
|
|
2011
|
+
const pubkey = accountKeys.get(keyIndex);
|
|
2012
|
+
|
|
2013
|
+
if (pubkey === undefined) {
|
|
2014
|
+
throw new Error(`Failed to find key for account key index ${keyIndex}`);
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
const isSigner = keyIndex < numRequiredSignatures;
|
|
2018
|
+
let isWritable;
|
|
2019
|
+
|
|
2020
|
+
if (isSigner) {
|
|
2021
|
+
isWritable = keyIndex < numWritableSignedAccounts;
|
|
2022
|
+
} else if (keyIndex < accountKeys.staticAccountKeys.length) {
|
|
2023
|
+
isWritable = keyIndex - numRequiredSignatures < numWritableUnsignedAccounts;
|
|
2024
|
+
} else {
|
|
2025
|
+
isWritable = keyIndex - accountKeys.staticAccountKeys.length < // accountKeysFromLookups cannot be undefined because we already found a pubkey for this index above
|
|
2026
|
+
accountKeys.accountKeysFromLookups.writable.length;
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
keys.push({
|
|
2030
|
+
pubkey,
|
|
2031
|
+
isSigner: keyIndex < header.numRequiredSignatures,
|
|
2032
|
+
isWritable
|
|
2033
|
+
});
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
const programId = accountKeys.get(compiledIx.programIdIndex);
|
|
2037
|
+
|
|
2038
|
+
if (programId === undefined) {
|
|
2039
|
+
throw new Error(`Failed to find program id for program id index ${compiledIx.programIdIndex}`);
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
instructions.push(new TransactionInstruction({
|
|
2043
|
+
programId,
|
|
2044
|
+
data: toBuffer(compiledIx.data),
|
|
2045
|
+
keys
|
|
2046
|
+
}));
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
return new TransactionMessage({
|
|
2050
|
+
payerKey,
|
|
2051
|
+
instructions,
|
|
2052
|
+
recentBlockhash
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
compileToLegacyMessage() {
|
|
2057
|
+
return Message.compile({
|
|
2058
|
+
payerKey: this.payerKey,
|
|
2059
|
+
recentBlockhash: this.recentBlockhash,
|
|
2060
|
+
instructions: this.instructions
|
|
2061
|
+
});
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
compileToV0Message(addressLookupTableAccounts) {
|
|
2065
|
+
return MessageV0.compile({
|
|
2066
|
+
payerKey: this.payerKey,
|
|
2067
|
+
recentBlockhash: this.recentBlockhash,
|
|
2068
|
+
instructions: this.instructions,
|
|
2069
|
+
addressLookupTableAccounts
|
|
2070
|
+
});
|
|
2071
|
+
}
|
|
2072
|
+
|
|
2073
|
+
}
|
|
2074
|
+
|
|
1873
2075
|
/**
|
|
1874
2076
|
* Versioned transaction class
|
|
1875
2077
|
*/
|
|
@@ -6173,10 +6375,44 @@ class Connection {
|
|
|
6173
6375
|
}
|
|
6174
6376
|
/**
|
|
6175
6377
|
* Simulate a transaction
|
|
6378
|
+
*
|
|
6379
|
+
* @deprecated Instead, call {@link simulateTransaction} with {@link
|
|
6380
|
+
* VersionedTransaction} and {@link SimulateTransactionConfig} parameters
|
|
6176
6381
|
*/
|
|
6177
6382
|
|
|
6178
6383
|
|
|
6179
|
-
|
|
6384
|
+
/**
|
|
6385
|
+
* Simulate a transaction
|
|
6386
|
+
*/
|
|
6387
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
6388
|
+
async simulateTransaction(transactionOrMessage, configOrSigners, includeAccounts) {
|
|
6389
|
+
if ('message' in transactionOrMessage) {
|
|
6390
|
+
const versionedTx = transactionOrMessage;
|
|
6391
|
+
const wireTransaction = versionedTx.serialize();
|
|
6392
|
+
const encodedTransaction = buffer.Buffer.from(wireTransaction).toString('base64');
|
|
6393
|
+
|
|
6394
|
+
if (Array.isArray(configOrSigners) || includeAccounts !== undefined) {
|
|
6395
|
+
throw new Error('Invalid arguments');
|
|
6396
|
+
}
|
|
6397
|
+
|
|
6398
|
+
const config = configOrSigners || {};
|
|
6399
|
+
config.encoding = 'base64';
|
|
6400
|
+
|
|
6401
|
+
if (!('commitment' in config)) {
|
|
6402
|
+
config.commitment = this.commitment;
|
|
6403
|
+
}
|
|
6404
|
+
|
|
6405
|
+
const args = [encodedTransaction, config];
|
|
6406
|
+
const unsafeRes = await this._rpcRequest('simulateTransaction', args);
|
|
6407
|
+
const res = superstruct.create(unsafeRes, SimulatedTransactionResponseStruct);
|
|
6408
|
+
|
|
6409
|
+
if ('error' in res) {
|
|
6410
|
+
throw new Error('failed to simulate transaction: ' + res.error.message);
|
|
6411
|
+
}
|
|
6412
|
+
|
|
6413
|
+
return res.result;
|
|
6414
|
+
}
|
|
6415
|
+
|
|
6180
6416
|
let transaction;
|
|
6181
6417
|
|
|
6182
6418
|
if (transactionOrMessage instanceof Transaction) {
|
|
@@ -6192,6 +6428,12 @@ class Connection {
|
|
|
6192
6428
|
transaction._message = transaction._json = undefined;
|
|
6193
6429
|
}
|
|
6194
6430
|
|
|
6431
|
+
if (configOrSigners !== undefined && !Array.isArray(configOrSigners)) {
|
|
6432
|
+
throw new Error('Invalid arguments');
|
|
6433
|
+
}
|
|
6434
|
+
|
|
6435
|
+
const signers = configOrSigners;
|
|
6436
|
+
|
|
6195
6437
|
if (transaction.nonceInfo && signers) {
|
|
6196
6438
|
transaction.sign(...signers);
|
|
6197
6439
|
} else {
|
|
@@ -6272,12 +6514,34 @@ class Connection {
|
|
|
6272
6514
|
|
|
6273
6515
|
return res.result;
|
|
6274
6516
|
}
|
|
6517
|
+
/**
|
|
6518
|
+
* Sign and send a transaction
|
|
6519
|
+
*
|
|
6520
|
+
* @deprecated Instead, call {@link sendTransaction} with a {@link
|
|
6521
|
+
* VersionedTransaction}
|
|
6522
|
+
*/
|
|
6523
|
+
|
|
6524
|
+
|
|
6275
6525
|
/**
|
|
6276
6526
|
* Sign and send a transaction
|
|
6277
6527
|
*/
|
|
6528
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
6529
|
+
async sendTransaction(transaction, signersOrOptions, options) {
|
|
6530
|
+
if ('message' in transaction) {
|
|
6531
|
+
if (signersOrOptions && Array.isArray(signersOrOptions)) {
|
|
6532
|
+
throw new Error('Invalid arguments');
|
|
6533
|
+
}
|
|
6534
|
+
|
|
6535
|
+
const wireTransaction = transaction.serialize();
|
|
6536
|
+
return await this.sendRawTransaction(wireTransaction, options);
|
|
6537
|
+
}
|
|
6538
|
+
|
|
6539
|
+
if (signersOrOptions === undefined || !Array.isArray(signersOrOptions)) {
|
|
6540
|
+
throw new Error('Invalid arguments');
|
|
6541
|
+
}
|
|
6278
6542
|
|
|
6543
|
+
const signers = signersOrOptions;
|
|
6279
6544
|
|
|
6280
|
-
async sendTransaction(transaction, signers, options) {
|
|
6281
6545
|
if (transaction.nonceInfo) {
|
|
6282
6546
|
transaction.sign(...signers);
|
|
6283
6547
|
} else {
|
|
@@ -7804,7 +8068,7 @@ class Secp256k1Program {
|
|
|
7804
8068
|
assert(publicKey.length === PUBLIC_KEY_BYTES, `Public key must be ${PUBLIC_KEY_BYTES} bytes but received ${publicKey.length} bytes`);
|
|
7805
8069
|
|
|
7806
8070
|
try {
|
|
7807
|
-
return buffer.Buffer.from(
|
|
8071
|
+
return buffer.Buffer.from(sha3.keccak_256(toBuffer(publicKey))).slice(-ETHEREUM_ADDRESS_BYTES);
|
|
7808
8072
|
} catch (error) {
|
|
7809
8073
|
throw new Error(`Error constructing Ethereum address: ${error}`);
|
|
7810
8074
|
}
|
|
@@ -7904,7 +8168,7 @@ class Secp256k1Program {
|
|
|
7904
8168
|
/* isCompressed */
|
|
7905
8169
|
).slice(1); // throw away leading byte
|
|
7906
8170
|
|
|
7907
|
-
const messageHash = buffer.Buffer.from(
|
|
8171
|
+
const messageHash = buffer.Buffer.from(sha3.keccak_256(toBuffer(message)));
|
|
7908
8172
|
const [signature, recoveryId] = ecdsaSign(messageHash, privateKey);
|
|
7909
8173
|
return this.createInstructionWithPublicKey({
|
|
7910
8174
|
publicKey,
|
|
@@ -8798,6 +9062,33 @@ class VoteInstruction {
|
|
|
8798
9062
|
}
|
|
8799
9063
|
};
|
|
8800
9064
|
}
|
|
9065
|
+
/**
|
|
9066
|
+
* Decode an authorize instruction and retrieve the instruction params.
|
|
9067
|
+
*/
|
|
9068
|
+
|
|
9069
|
+
|
|
9070
|
+
static decodeAuthorizeWithSeed(instruction) {
|
|
9071
|
+
this.checkProgramId(instruction.programId);
|
|
9072
|
+
this.checkKeyLength(instruction.keys, 3);
|
|
9073
|
+
const {
|
|
9074
|
+
voteAuthorizeWithSeedArgs: {
|
|
9075
|
+
currentAuthorityDerivedKeyOwnerPubkey,
|
|
9076
|
+
currentAuthorityDerivedKeySeed,
|
|
9077
|
+
newAuthorized,
|
|
9078
|
+
voteAuthorizationType
|
|
9079
|
+
}
|
|
9080
|
+
} = decodeData$1(VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed, instruction.data);
|
|
9081
|
+
return {
|
|
9082
|
+
currentAuthorityDerivedKeyBasePubkey: instruction.keys[2].pubkey,
|
|
9083
|
+
currentAuthorityDerivedKeyOwnerPubkey: new PublicKey(currentAuthorityDerivedKeyOwnerPubkey),
|
|
9084
|
+
currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
|
|
9085
|
+
newAuthorizedPubkey: new PublicKey(newAuthorized),
|
|
9086
|
+
voteAuthorizationType: {
|
|
9087
|
+
index: voteAuthorizationType
|
|
9088
|
+
},
|
|
9089
|
+
votePubkey: instruction.keys[0].pubkey
|
|
9090
|
+
};
|
|
9091
|
+
}
|
|
8801
9092
|
/**
|
|
8802
9093
|
* Decode a withdraw instruction and retrieve the instruction params.
|
|
8803
9094
|
*/
|
|
@@ -8854,6 +9145,10 @@ const VOTE_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
|
8854
9145
|
Withdraw: {
|
|
8855
9146
|
index: 3,
|
|
8856
9147
|
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), BufferLayout__namespace.ns64('lamports')])
|
|
9148
|
+
},
|
|
9149
|
+
AuthorizeWithSeed: {
|
|
9150
|
+
index: 10,
|
|
9151
|
+
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), voteAuthorizeWithSeedArgs()])
|
|
8857
9152
|
}
|
|
8858
9153
|
});
|
|
8859
9154
|
/**
|
|
@@ -8982,6 +9277,49 @@ class VoteProgram {
|
|
|
8982
9277
|
data
|
|
8983
9278
|
});
|
|
8984
9279
|
}
|
|
9280
|
+
/**
|
|
9281
|
+
* Generate a transaction that authorizes a new Voter or Withdrawer on the Vote account
|
|
9282
|
+
* where the current Voter or Withdrawer authority is a derived key.
|
|
9283
|
+
*/
|
|
9284
|
+
|
|
9285
|
+
|
|
9286
|
+
static authorizeWithSeed(params) {
|
|
9287
|
+
const {
|
|
9288
|
+
currentAuthorityDerivedKeyBasePubkey,
|
|
9289
|
+
currentAuthorityDerivedKeyOwnerPubkey,
|
|
9290
|
+
currentAuthorityDerivedKeySeed,
|
|
9291
|
+
newAuthorizedPubkey,
|
|
9292
|
+
voteAuthorizationType,
|
|
9293
|
+
votePubkey
|
|
9294
|
+
} = params;
|
|
9295
|
+
const type = VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed;
|
|
9296
|
+
const data = encodeData(type, {
|
|
9297
|
+
voteAuthorizeWithSeedArgs: {
|
|
9298
|
+
currentAuthorityDerivedKeyOwnerPubkey: toBuffer(currentAuthorityDerivedKeyOwnerPubkey.toBuffer()),
|
|
9299
|
+
currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
|
|
9300
|
+
newAuthorized: toBuffer(newAuthorizedPubkey.toBuffer()),
|
|
9301
|
+
voteAuthorizationType: voteAuthorizationType.index
|
|
9302
|
+
}
|
|
9303
|
+
});
|
|
9304
|
+
const keys = [{
|
|
9305
|
+
pubkey: votePubkey,
|
|
9306
|
+
isSigner: false,
|
|
9307
|
+
isWritable: true
|
|
9308
|
+
}, {
|
|
9309
|
+
pubkey: SYSVAR_CLOCK_PUBKEY,
|
|
9310
|
+
isSigner: false,
|
|
9311
|
+
isWritable: false
|
|
9312
|
+
}, {
|
|
9313
|
+
pubkey: currentAuthorityDerivedKeyBasePubkey,
|
|
9314
|
+
isSigner: true,
|
|
9315
|
+
isWritable: false
|
|
9316
|
+
}];
|
|
9317
|
+
return new Transaction().add({
|
|
9318
|
+
keys,
|
|
9319
|
+
programId: this.programId,
|
|
9320
|
+
data
|
|
9321
|
+
});
|
|
9322
|
+
}
|
|
8985
9323
|
/**
|
|
8986
9324
|
* Generate a transaction to withdraw from a Vote account.
|
|
8987
9325
|
*/
|
|
@@ -9363,6 +9701,7 @@ exports.Transaction = Transaction;
|
|
|
9363
9701
|
exports.TransactionExpiredBlockheightExceededError = TransactionExpiredBlockheightExceededError;
|
|
9364
9702
|
exports.TransactionExpiredTimeoutError = TransactionExpiredTimeoutError;
|
|
9365
9703
|
exports.TransactionInstruction = TransactionInstruction;
|
|
9704
|
+
exports.TransactionMessage = TransactionMessage;
|
|
9366
9705
|
exports.VALIDATOR_INFO_KEY = VALIDATOR_INFO_KEY;
|
|
9367
9706
|
exports.VERSION_PREFIX_MASK = VERSION_PREFIX_MASK;
|
|
9368
9707
|
exports.VOTE_PROGRAM_ID = VOTE_PROGRAM_ID;
|