@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.cjs.js
CHANGED
|
@@ -17,7 +17,7 @@ var RpcClient = require('jayson/lib/client/browser');
|
|
|
17
17
|
var http = require('http');
|
|
18
18
|
var https = require('https');
|
|
19
19
|
var nodeFetch = require('node-fetch');
|
|
20
|
-
var sha3 = require('
|
|
20
|
+
var sha3 = require('@noble/hashes/sha3');
|
|
21
21
|
var hmac = require('@noble/hashes/hmac');
|
|
22
22
|
var secp256k1 = require('@noble/secp256k1');
|
|
23
23
|
|
|
@@ -49,7 +49,6 @@ var RpcClient__default = /*#__PURE__*/_interopDefaultLegacy(RpcClient);
|
|
|
49
49
|
var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
|
|
50
50
|
var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
|
|
51
51
|
var nodeFetch__namespace = /*#__PURE__*/_interopNamespace(nodeFetch);
|
|
52
|
-
var sha3__default = /*#__PURE__*/_interopDefaultLegacy(sha3);
|
|
53
52
|
var secp256k1__namespace = /*#__PURE__*/_interopNamespace(secp256k1);
|
|
54
53
|
|
|
55
54
|
/**
|
|
@@ -523,7 +522,6 @@ class MessageAccountKeys {
|
|
|
523
522
|
/**
|
|
524
523
|
* Layout for a public key
|
|
525
524
|
*/
|
|
526
|
-
|
|
527
525
|
const publicKey = (property = 'publicKey') => {
|
|
528
526
|
return BufferLayout__namespace.blob(32, property);
|
|
529
527
|
};
|
|
@@ -587,6 +585,13 @@ const lockup = (property = 'lockup') => {
|
|
|
587
585
|
const voteInit = (property = 'voteInit') => {
|
|
588
586
|
return BufferLayout__namespace.struct([publicKey('nodePubkey'), publicKey('authorizedVoter'), publicKey('authorizedWithdrawer'), BufferLayout__namespace.u8('commission')], property);
|
|
589
587
|
};
|
|
588
|
+
/**
|
|
589
|
+
* Layout for a VoteAuthorizeWithSeedArgs object
|
|
590
|
+
*/
|
|
591
|
+
|
|
592
|
+
const voteAuthorizeWithSeedArgs = (property = 'voteAuthorizeWithSeedArgs') => {
|
|
593
|
+
return BufferLayout__namespace.struct([BufferLayout__namespace.u32('voteAuthorizationType'), publicKey('currentAuthorityDerivedKeyOwnerPubkey'), rustString('currentAuthorityDerivedKeySeed'), publicKey('newAuthorized')], property);
|
|
594
|
+
};
|
|
590
595
|
function getAlloc(type, fields) {
|
|
591
596
|
const getItemAlloc = item => {
|
|
592
597
|
if (item.span >= 0) {
|
|
@@ -599,6 +604,11 @@ function getAlloc(type, fields) {
|
|
|
599
604
|
if (Array.isArray(field)) {
|
|
600
605
|
return field.length * getItemAlloc(item.elementLayout);
|
|
601
606
|
}
|
|
607
|
+
} else if ('fields' in item) {
|
|
608
|
+
// This is a `Structure` whose size needs to be recursively measured.
|
|
609
|
+
return getAlloc({
|
|
610
|
+
layout: item
|
|
611
|
+
}, fields[item.property]);
|
|
602
612
|
} // Couldn't determine allocated size of layout
|
|
603
613
|
|
|
604
614
|
|
|
@@ -645,6 +655,129 @@ function encodeLength(bytes, len) {
|
|
|
645
655
|
}
|
|
646
656
|
}
|
|
647
657
|
|
|
658
|
+
function assert (condition, message) {
|
|
659
|
+
if (!condition) {
|
|
660
|
+
throw new Error(message || 'Assertion failed');
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
class CompiledKeys {
|
|
665
|
+
constructor(payer, keyMetaMap) {
|
|
666
|
+
this.payer = void 0;
|
|
667
|
+
this.keyMetaMap = void 0;
|
|
668
|
+
this.payer = payer;
|
|
669
|
+
this.keyMetaMap = keyMetaMap;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
static compile(instructions, payer) {
|
|
673
|
+
const keyMetaMap = new Map();
|
|
674
|
+
|
|
675
|
+
const getOrInsertDefault = pubkey => {
|
|
676
|
+
const address = pubkey.toBase58();
|
|
677
|
+
let keyMeta = keyMetaMap.get(address);
|
|
678
|
+
|
|
679
|
+
if (keyMeta === undefined) {
|
|
680
|
+
keyMeta = {
|
|
681
|
+
isSigner: false,
|
|
682
|
+
isWritable: false,
|
|
683
|
+
isInvoked: false
|
|
684
|
+
};
|
|
685
|
+
keyMetaMap.set(address, keyMeta);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
return keyMeta;
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
const payerKeyMeta = getOrInsertDefault(payer);
|
|
692
|
+
payerKeyMeta.isSigner = true;
|
|
693
|
+
payerKeyMeta.isWritable = true;
|
|
694
|
+
|
|
695
|
+
for (const ix of instructions) {
|
|
696
|
+
getOrInsertDefault(ix.programId).isInvoked = true;
|
|
697
|
+
|
|
698
|
+
for (const accountMeta of ix.keys) {
|
|
699
|
+
const keyMeta = getOrInsertDefault(accountMeta.pubkey);
|
|
700
|
+
keyMeta.isSigner || (keyMeta.isSigner = accountMeta.isSigner);
|
|
701
|
+
keyMeta.isWritable || (keyMeta.isWritable = accountMeta.isWritable);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
return new CompiledKeys(payer, keyMetaMap);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
getMessageComponents() {
|
|
709
|
+
const mapEntries = [...this.keyMetaMap.entries()];
|
|
710
|
+
assert(mapEntries.length <= 256, 'Max static account keys length exceeded');
|
|
711
|
+
const writableSigners = mapEntries.filter(([, meta]) => meta.isSigner && meta.isWritable);
|
|
712
|
+
const readonlySigners = mapEntries.filter(([, meta]) => meta.isSigner && !meta.isWritable);
|
|
713
|
+
const writableNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && meta.isWritable);
|
|
714
|
+
const readonlyNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && !meta.isWritable);
|
|
715
|
+
const header = {
|
|
716
|
+
numRequiredSignatures: writableSigners.length + readonlySigners.length,
|
|
717
|
+
numReadonlySignedAccounts: readonlySigners.length,
|
|
718
|
+
numReadonlyUnsignedAccounts: readonlyNonSigners.length
|
|
719
|
+
}; // sanity checks
|
|
720
|
+
|
|
721
|
+
{
|
|
722
|
+
assert(writableSigners.length > 0, 'Expected at least one writable signer key');
|
|
723
|
+
const [payerAddress] = writableSigners[0];
|
|
724
|
+
assert(payerAddress === this.payer.toBase58(), 'Expected first writable signer key to be the fee payer');
|
|
725
|
+
}
|
|
726
|
+
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))];
|
|
727
|
+
return [header, staticAccountKeys];
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
extractTableLookup(lookupTable) {
|
|
731
|
+
const [writableIndexes, drainedWritableKeys] = this.drainKeysFoundInLookupTable(lookupTable.state.addresses, keyMeta => !keyMeta.isSigner && !keyMeta.isInvoked && keyMeta.isWritable);
|
|
732
|
+
const [readonlyIndexes, drainedReadonlyKeys] = this.drainKeysFoundInLookupTable(lookupTable.state.addresses, keyMeta => !keyMeta.isSigner && !keyMeta.isInvoked && !keyMeta.isWritable); // Don't extract lookup if no keys were found
|
|
733
|
+
|
|
734
|
+
if (writableIndexes.length === 0 && readonlyIndexes.length === 0) {
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
return [{
|
|
739
|
+
accountKey: lookupTable.key,
|
|
740
|
+
writableIndexes,
|
|
741
|
+
readonlyIndexes
|
|
742
|
+
}, {
|
|
743
|
+
writable: drainedWritableKeys,
|
|
744
|
+
readonly: drainedReadonlyKeys
|
|
745
|
+
}];
|
|
746
|
+
}
|
|
747
|
+
/** @internal */
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
drainKeysFoundInLookupTable(lookupTableEntries, keyMetaFilter) {
|
|
751
|
+
const lookupTableIndexes = new Array();
|
|
752
|
+
const drainedKeys = new Array();
|
|
753
|
+
|
|
754
|
+
for (const [address, keyMeta] of this.keyMetaMap.entries()) {
|
|
755
|
+
if (keyMetaFilter(keyMeta)) {
|
|
756
|
+
const key = new PublicKey(address);
|
|
757
|
+
const lookupTableIndex = lookupTableEntries.findIndex(entry => entry.equals(key));
|
|
758
|
+
|
|
759
|
+
if (lookupTableIndex >= 0) {
|
|
760
|
+
assert(lookupTableIndex < 256, 'Max lookup table index exceeded');
|
|
761
|
+
lookupTableIndexes.push(lookupTableIndex);
|
|
762
|
+
drainedKeys.push(key);
|
|
763
|
+
this.keyMetaMap.delete(address);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
return [lookupTableIndexes, drainedKeys];
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* An instruction to execute by a program
|
|
775
|
+
*
|
|
776
|
+
* @property {number} programIdIndex
|
|
777
|
+
* @property {number[]} accounts
|
|
778
|
+
* @property {string} data
|
|
779
|
+
*/
|
|
780
|
+
|
|
648
781
|
/**
|
|
649
782
|
* List of instructions to be processed atomically
|
|
650
783
|
*/
|
|
@@ -682,6 +815,27 @@ class Message {
|
|
|
682
815
|
return [];
|
|
683
816
|
}
|
|
684
817
|
|
|
818
|
+
getAccountKeys() {
|
|
819
|
+
return new MessageAccountKeys(this.staticAccountKeys);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
static compile(args) {
|
|
823
|
+
const compiledKeys = CompiledKeys.compile(args.instructions, args.payerKey);
|
|
824
|
+
const [header, staticAccountKeys] = compiledKeys.getMessageComponents();
|
|
825
|
+
const accountKeys = new MessageAccountKeys(staticAccountKeys);
|
|
826
|
+
const instructions = accountKeys.compileInstructions(args.instructions).map(ix => ({
|
|
827
|
+
programIdIndex: ix.programIdIndex,
|
|
828
|
+
accounts: ix.accountKeyIndexes,
|
|
829
|
+
data: bs58__default["default"].encode(ix.data)
|
|
830
|
+
}));
|
|
831
|
+
return new Message({
|
|
832
|
+
header,
|
|
833
|
+
accountKeys: staticAccountKeys,
|
|
834
|
+
recentBlockhash: args.recentBlockhash,
|
|
835
|
+
instructions
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
|
|
685
839
|
isAccountSigner(index) {
|
|
686
840
|
return index < this.header.numRequiredSignatures;
|
|
687
841
|
}
|
|
@@ -771,7 +925,7 @@ class Message {
|
|
|
771
925
|
for (let i = 0; i < accountCount; i++) {
|
|
772
926
|
const account = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
773
927
|
byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
|
|
774
|
-
accountKeys.push(
|
|
928
|
+
accountKeys.push(new PublicKey(buffer.Buffer.from(account)));
|
|
775
929
|
}
|
|
776
930
|
|
|
777
931
|
const recentBlockhash = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
@@ -810,141 +964,87 @@ class Message {
|
|
|
810
964
|
|
|
811
965
|
}
|
|
812
966
|
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
}
|
|
817
|
-
}
|
|
967
|
+
/**
|
|
968
|
+
* Message constructor arguments
|
|
969
|
+
*/
|
|
818
970
|
|
|
819
|
-
class
|
|
820
|
-
constructor(
|
|
821
|
-
this.
|
|
822
|
-
this.
|
|
823
|
-
this.
|
|
824
|
-
this.
|
|
971
|
+
class MessageV0 {
|
|
972
|
+
constructor(args) {
|
|
973
|
+
this.header = void 0;
|
|
974
|
+
this.staticAccountKeys = void 0;
|
|
975
|
+
this.recentBlockhash = void 0;
|
|
976
|
+
this.compiledInstructions = void 0;
|
|
977
|
+
this.addressTableLookups = void 0;
|
|
978
|
+
this.header = args.header;
|
|
979
|
+
this.staticAccountKeys = args.staticAccountKeys;
|
|
980
|
+
this.recentBlockhash = args.recentBlockhash;
|
|
981
|
+
this.compiledInstructions = args.compiledInstructions;
|
|
982
|
+
this.addressTableLookups = args.addressTableLookups;
|
|
825
983
|
}
|
|
826
984
|
|
|
827
|
-
|
|
828
|
-
|
|
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;
|
|
985
|
+
get version() {
|
|
986
|
+
return 0;
|
|
987
|
+
}
|
|
849
988
|
|
|
850
|
-
|
|
851
|
-
|
|
989
|
+
get numAccountKeysFromLookups() {
|
|
990
|
+
let count = 0;
|
|
852
991
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
keyMeta.isSigner || (keyMeta.isSigner = accountMeta.isSigner);
|
|
856
|
-
keyMeta.isWritable || (keyMeta.isWritable = accountMeta.isWritable);
|
|
857
|
-
}
|
|
992
|
+
for (const lookup of this.addressTableLookups) {
|
|
993
|
+
count += lookup.readonlyIndexes.length + lookup.writableIndexes.length;
|
|
858
994
|
}
|
|
859
995
|
|
|
860
|
-
return
|
|
996
|
+
return count;
|
|
861
997
|
}
|
|
862
998
|
|
|
863
|
-
|
|
864
|
-
|
|
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
|
-
}
|
|
999
|
+
getAccountKeys(args) {
|
|
1000
|
+
let accountKeysFromLookups;
|
|
884
1001
|
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
1002
|
+
if (args && 'accountKeysFromLookups' in args) {
|
|
1003
|
+
if (this.numAccountKeysFromLookups != args.accountKeysFromLookups.writable.length + args.accountKeysFromLookups.readonly.length) {
|
|
1004
|
+
throw new Error('Failed to get account keys because of a mismatch in the number of account keys from lookups');
|
|
1005
|
+
}
|
|
888
1006
|
|
|
889
|
-
|
|
890
|
-
|
|
1007
|
+
accountKeysFromLookups = args.accountKeysFromLookups;
|
|
1008
|
+
} else if (args && 'addressLookupTableAccounts' in args) {
|
|
1009
|
+
accountKeysFromLookups = this.resolveAddressTableLookups(args.addressLookupTableAccounts);
|
|
1010
|
+
} else if (this.addressTableLookups.length > 0) {
|
|
1011
|
+
throw new Error('Failed to get account keys because address table lookups were not resolved');
|
|
891
1012
|
}
|
|
892
1013
|
|
|
893
|
-
return
|
|
894
|
-
accountKey: lookupTable.key,
|
|
895
|
-
writableIndexes,
|
|
896
|
-
readonlyIndexes
|
|
897
|
-
}, {
|
|
898
|
-
writable: drainedWritableKeys,
|
|
899
|
-
readonly: drainedReadonlyKeys
|
|
900
|
-
}];
|
|
1014
|
+
return new MessageAccountKeys(this.staticAccountKeys, accountKeysFromLookups);
|
|
901
1015
|
}
|
|
902
|
-
/** @internal */
|
|
903
1016
|
|
|
1017
|
+
resolveAddressTableLookups(addressLookupTableAccounts) {
|
|
1018
|
+
const accountKeysFromLookups = {
|
|
1019
|
+
writable: [],
|
|
1020
|
+
readonly: []
|
|
1021
|
+
};
|
|
904
1022
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
const drainedKeys = new Array();
|
|
1023
|
+
for (const tableLookup of this.addressTableLookups) {
|
|
1024
|
+
const tableAccount = addressLookupTableAccounts.find(account => account.key.equals(tableLookup.accountKey));
|
|
908
1025
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
const lookupTableIndex = lookupTableEntries.findIndex(entry => entry.equals(key));
|
|
1026
|
+
if (!tableAccount) {
|
|
1027
|
+
throw new Error(`Failed to find address lookup table account for table key ${tableLookup.accountKey.toBase58()}`);
|
|
1028
|
+
}
|
|
913
1029
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1030
|
+
for (const index of tableLookup.writableIndexes) {
|
|
1031
|
+
if (index < tableAccount.state.addresses.length) {
|
|
1032
|
+
accountKeysFromLookups.writable.push(tableAccount.state.addresses[index]);
|
|
1033
|
+
} else {
|
|
1034
|
+
throw new Error(`Failed to find address for index ${index} in address lookup table ${tableLookup.accountKey.toBase58()}`);
|
|
919
1035
|
}
|
|
920
1036
|
}
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
return [lookupTableIndexes, drainedKeys];
|
|
924
|
-
}
|
|
925
1037
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
this.header = void 0;
|
|
935
|
-
this.staticAccountKeys = void 0;
|
|
936
|
-
this.recentBlockhash = void 0;
|
|
937
|
-
this.compiledInstructions = void 0;
|
|
938
|
-
this.addressTableLookups = void 0;
|
|
939
|
-
this.header = args.header;
|
|
940
|
-
this.staticAccountKeys = args.staticAccountKeys;
|
|
941
|
-
this.recentBlockhash = args.recentBlockhash;
|
|
942
|
-
this.compiledInstructions = args.compiledInstructions;
|
|
943
|
-
this.addressTableLookups = args.addressTableLookups;
|
|
944
|
-
}
|
|
1038
|
+
for (const index of tableLookup.readonlyIndexes) {
|
|
1039
|
+
if (index < tableAccount.state.addresses.length) {
|
|
1040
|
+
accountKeysFromLookups.readonly.push(tableAccount.state.addresses[index]);
|
|
1041
|
+
} else {
|
|
1042
|
+
throw new Error(`Failed to find address for index ${index} in address lookup table ${tableLookup.accountKey.toBase58()}`);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
945
1046
|
|
|
946
|
-
|
|
947
|
-
return 0;
|
|
1047
|
+
return accountKeysFromLookups;
|
|
948
1048
|
}
|
|
949
1049
|
|
|
950
1050
|
static compile(args) {
|
|
@@ -1876,6 +1976,108 @@ class Transaction {
|
|
|
1876
1976
|
|
|
1877
1977
|
}
|
|
1878
1978
|
|
|
1979
|
+
class TransactionMessage {
|
|
1980
|
+
constructor(args) {
|
|
1981
|
+
this.payerKey = void 0;
|
|
1982
|
+
this.instructions = void 0;
|
|
1983
|
+
this.recentBlockhash = void 0;
|
|
1984
|
+
this.payerKey = args.payerKey;
|
|
1985
|
+
this.instructions = args.instructions;
|
|
1986
|
+
this.recentBlockhash = args.recentBlockhash;
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
static decompile(message, args) {
|
|
1990
|
+
const {
|
|
1991
|
+
header,
|
|
1992
|
+
compiledInstructions,
|
|
1993
|
+
recentBlockhash
|
|
1994
|
+
} = message;
|
|
1995
|
+
const {
|
|
1996
|
+
numRequiredSignatures,
|
|
1997
|
+
numReadonlySignedAccounts,
|
|
1998
|
+
numReadonlyUnsignedAccounts
|
|
1999
|
+
} = header;
|
|
2000
|
+
const numWritableSignedAccounts = numRequiredSignatures - numReadonlySignedAccounts;
|
|
2001
|
+
assert(numWritableSignedAccounts > 0, 'Message header is invalid');
|
|
2002
|
+
const numWritableUnsignedAccounts = message.staticAccountKeys.length - numReadonlyUnsignedAccounts;
|
|
2003
|
+
assert(numWritableUnsignedAccounts >= 0, 'Message header is invalid');
|
|
2004
|
+
const accountKeys = message.getAccountKeys(args);
|
|
2005
|
+
const payerKey = accountKeys.get(0);
|
|
2006
|
+
|
|
2007
|
+
if (payerKey === undefined) {
|
|
2008
|
+
throw new Error('Failed to decompile message because no account keys were found');
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
const instructions = [];
|
|
2012
|
+
|
|
2013
|
+
for (const compiledIx of compiledInstructions) {
|
|
2014
|
+
const keys = [];
|
|
2015
|
+
|
|
2016
|
+
for (const keyIndex of compiledIx.accountKeyIndexes) {
|
|
2017
|
+
const pubkey = accountKeys.get(keyIndex);
|
|
2018
|
+
|
|
2019
|
+
if (pubkey === undefined) {
|
|
2020
|
+
throw new Error(`Failed to find key for account key index ${keyIndex}`);
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
const isSigner = keyIndex < numRequiredSignatures;
|
|
2024
|
+
let isWritable;
|
|
2025
|
+
|
|
2026
|
+
if (isSigner) {
|
|
2027
|
+
isWritable = keyIndex < numWritableSignedAccounts;
|
|
2028
|
+
} else if (keyIndex < accountKeys.staticAccountKeys.length) {
|
|
2029
|
+
isWritable = keyIndex - numRequiredSignatures < numWritableUnsignedAccounts;
|
|
2030
|
+
} else {
|
|
2031
|
+
isWritable = keyIndex - accountKeys.staticAccountKeys.length < // accountKeysFromLookups cannot be undefined because we already found a pubkey for this index above
|
|
2032
|
+
accountKeys.accountKeysFromLookups.writable.length;
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
keys.push({
|
|
2036
|
+
pubkey,
|
|
2037
|
+
isSigner: keyIndex < header.numRequiredSignatures,
|
|
2038
|
+
isWritable
|
|
2039
|
+
});
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
const programId = accountKeys.get(compiledIx.programIdIndex);
|
|
2043
|
+
|
|
2044
|
+
if (programId === undefined) {
|
|
2045
|
+
throw new Error(`Failed to find program id for program id index ${compiledIx.programIdIndex}`);
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
instructions.push(new TransactionInstruction({
|
|
2049
|
+
programId,
|
|
2050
|
+
data: toBuffer(compiledIx.data),
|
|
2051
|
+
keys
|
|
2052
|
+
}));
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
return new TransactionMessage({
|
|
2056
|
+
payerKey,
|
|
2057
|
+
instructions,
|
|
2058
|
+
recentBlockhash
|
|
2059
|
+
});
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
compileToLegacyMessage() {
|
|
2063
|
+
return Message.compile({
|
|
2064
|
+
payerKey: this.payerKey,
|
|
2065
|
+
recentBlockhash: this.recentBlockhash,
|
|
2066
|
+
instructions: this.instructions
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
compileToV0Message(addressLookupTableAccounts) {
|
|
2071
|
+
return MessageV0.compile({
|
|
2072
|
+
payerKey: this.payerKey,
|
|
2073
|
+
recentBlockhash: this.recentBlockhash,
|
|
2074
|
+
instructions: this.instructions,
|
|
2075
|
+
addressLookupTableAccounts
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
}
|
|
2080
|
+
|
|
1879
2081
|
/**
|
|
1880
2082
|
* Versioned transaction class
|
|
1881
2083
|
*/
|
|
@@ -6239,10 +6441,44 @@ class Connection {
|
|
|
6239
6441
|
}
|
|
6240
6442
|
/**
|
|
6241
6443
|
* Simulate a transaction
|
|
6444
|
+
*
|
|
6445
|
+
* @deprecated Instead, call {@link simulateTransaction} with {@link
|
|
6446
|
+
* VersionedTransaction} and {@link SimulateTransactionConfig} parameters
|
|
6242
6447
|
*/
|
|
6243
6448
|
|
|
6244
6449
|
|
|
6245
|
-
|
|
6450
|
+
/**
|
|
6451
|
+
* Simulate a transaction
|
|
6452
|
+
*/
|
|
6453
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
6454
|
+
async simulateTransaction(transactionOrMessage, configOrSigners, includeAccounts) {
|
|
6455
|
+
if ('message' in transactionOrMessage) {
|
|
6456
|
+
const versionedTx = transactionOrMessage;
|
|
6457
|
+
const wireTransaction = versionedTx.serialize();
|
|
6458
|
+
const encodedTransaction = buffer.Buffer.from(wireTransaction).toString('base64');
|
|
6459
|
+
|
|
6460
|
+
if (Array.isArray(configOrSigners) || includeAccounts !== undefined) {
|
|
6461
|
+
throw new Error('Invalid arguments');
|
|
6462
|
+
}
|
|
6463
|
+
|
|
6464
|
+
const config = configOrSigners || {};
|
|
6465
|
+
config.encoding = 'base64';
|
|
6466
|
+
|
|
6467
|
+
if (!('commitment' in config)) {
|
|
6468
|
+
config.commitment = this.commitment;
|
|
6469
|
+
}
|
|
6470
|
+
|
|
6471
|
+
const args = [encodedTransaction, config];
|
|
6472
|
+
const unsafeRes = await this._rpcRequest('simulateTransaction', args);
|
|
6473
|
+
const res = superstruct.create(unsafeRes, SimulatedTransactionResponseStruct);
|
|
6474
|
+
|
|
6475
|
+
if ('error' in res) {
|
|
6476
|
+
throw new Error('failed to simulate transaction: ' + res.error.message);
|
|
6477
|
+
}
|
|
6478
|
+
|
|
6479
|
+
return res.result;
|
|
6480
|
+
}
|
|
6481
|
+
|
|
6246
6482
|
let transaction;
|
|
6247
6483
|
|
|
6248
6484
|
if (transactionOrMessage instanceof Transaction) {
|
|
@@ -6258,6 +6494,12 @@ class Connection {
|
|
|
6258
6494
|
transaction._message = transaction._json = undefined;
|
|
6259
6495
|
}
|
|
6260
6496
|
|
|
6497
|
+
if (configOrSigners !== undefined && !Array.isArray(configOrSigners)) {
|
|
6498
|
+
throw new Error('Invalid arguments');
|
|
6499
|
+
}
|
|
6500
|
+
|
|
6501
|
+
const signers = configOrSigners;
|
|
6502
|
+
|
|
6261
6503
|
if (transaction.nonceInfo && signers) {
|
|
6262
6504
|
transaction.sign(...signers);
|
|
6263
6505
|
} else {
|
|
@@ -6338,12 +6580,34 @@ class Connection {
|
|
|
6338
6580
|
|
|
6339
6581
|
return res.result;
|
|
6340
6582
|
}
|
|
6583
|
+
/**
|
|
6584
|
+
* Sign and send a transaction
|
|
6585
|
+
*
|
|
6586
|
+
* @deprecated Instead, call {@link sendTransaction} with a {@link
|
|
6587
|
+
* VersionedTransaction}
|
|
6588
|
+
*/
|
|
6589
|
+
|
|
6590
|
+
|
|
6341
6591
|
/**
|
|
6342
6592
|
* Sign and send a transaction
|
|
6343
6593
|
*/
|
|
6594
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
6595
|
+
async sendTransaction(transaction, signersOrOptions, options) {
|
|
6596
|
+
if ('message' in transaction) {
|
|
6597
|
+
if (signersOrOptions && Array.isArray(signersOrOptions)) {
|
|
6598
|
+
throw new Error('Invalid arguments');
|
|
6599
|
+
}
|
|
6600
|
+
|
|
6601
|
+
const wireTransaction = transaction.serialize();
|
|
6602
|
+
return await this.sendRawTransaction(wireTransaction, options);
|
|
6603
|
+
}
|
|
6604
|
+
|
|
6605
|
+
if (signersOrOptions === undefined || !Array.isArray(signersOrOptions)) {
|
|
6606
|
+
throw new Error('Invalid arguments');
|
|
6607
|
+
}
|
|
6344
6608
|
|
|
6609
|
+
const signers = signersOrOptions;
|
|
6345
6610
|
|
|
6346
|
-
async sendTransaction(transaction, signers, options) {
|
|
6347
6611
|
if (transaction.nonceInfo) {
|
|
6348
6612
|
transaction.sign(...signers);
|
|
6349
6613
|
} else {
|
|
@@ -7870,7 +8134,7 @@ class Secp256k1Program {
|
|
|
7870
8134
|
assert(publicKey.length === PUBLIC_KEY_BYTES, `Public key must be ${PUBLIC_KEY_BYTES} bytes but received ${publicKey.length} bytes`);
|
|
7871
8135
|
|
|
7872
8136
|
try {
|
|
7873
|
-
return buffer.Buffer.from(
|
|
8137
|
+
return buffer.Buffer.from(sha3.keccak_256(toBuffer(publicKey))).slice(-ETHEREUM_ADDRESS_BYTES);
|
|
7874
8138
|
} catch (error) {
|
|
7875
8139
|
throw new Error(`Error constructing Ethereum address: ${error}`);
|
|
7876
8140
|
}
|
|
@@ -7970,7 +8234,7 @@ class Secp256k1Program {
|
|
|
7970
8234
|
/* isCompressed */
|
|
7971
8235
|
).slice(1); // throw away leading byte
|
|
7972
8236
|
|
|
7973
|
-
const messageHash = buffer.Buffer.from(
|
|
8237
|
+
const messageHash = buffer.Buffer.from(sha3.keccak_256(toBuffer(message)));
|
|
7974
8238
|
const [signature, recoveryId] = ecdsaSign(messageHash, privateKey);
|
|
7975
8239
|
return this.createInstructionWithPublicKey({
|
|
7976
8240
|
publicKey,
|
|
@@ -8864,6 +9128,33 @@ class VoteInstruction {
|
|
|
8864
9128
|
}
|
|
8865
9129
|
};
|
|
8866
9130
|
}
|
|
9131
|
+
/**
|
|
9132
|
+
* Decode an authorize instruction and retrieve the instruction params.
|
|
9133
|
+
*/
|
|
9134
|
+
|
|
9135
|
+
|
|
9136
|
+
static decodeAuthorizeWithSeed(instruction) {
|
|
9137
|
+
this.checkProgramId(instruction.programId);
|
|
9138
|
+
this.checkKeyLength(instruction.keys, 3);
|
|
9139
|
+
const {
|
|
9140
|
+
voteAuthorizeWithSeedArgs: {
|
|
9141
|
+
currentAuthorityDerivedKeyOwnerPubkey,
|
|
9142
|
+
currentAuthorityDerivedKeySeed,
|
|
9143
|
+
newAuthorized,
|
|
9144
|
+
voteAuthorizationType
|
|
9145
|
+
}
|
|
9146
|
+
} = decodeData$1(VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed, instruction.data);
|
|
9147
|
+
return {
|
|
9148
|
+
currentAuthorityDerivedKeyBasePubkey: instruction.keys[2].pubkey,
|
|
9149
|
+
currentAuthorityDerivedKeyOwnerPubkey: new PublicKey(currentAuthorityDerivedKeyOwnerPubkey),
|
|
9150
|
+
currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
|
|
9151
|
+
newAuthorizedPubkey: new PublicKey(newAuthorized),
|
|
9152
|
+
voteAuthorizationType: {
|
|
9153
|
+
index: voteAuthorizationType
|
|
9154
|
+
},
|
|
9155
|
+
votePubkey: instruction.keys[0].pubkey
|
|
9156
|
+
};
|
|
9157
|
+
}
|
|
8867
9158
|
/**
|
|
8868
9159
|
* Decode a withdraw instruction and retrieve the instruction params.
|
|
8869
9160
|
*/
|
|
@@ -8920,6 +9211,10 @@ const VOTE_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
|
8920
9211
|
Withdraw: {
|
|
8921
9212
|
index: 3,
|
|
8922
9213
|
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), BufferLayout__namespace.ns64('lamports')])
|
|
9214
|
+
},
|
|
9215
|
+
AuthorizeWithSeed: {
|
|
9216
|
+
index: 10,
|
|
9217
|
+
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), voteAuthorizeWithSeedArgs()])
|
|
8923
9218
|
}
|
|
8924
9219
|
});
|
|
8925
9220
|
/**
|
|
@@ -9048,6 +9343,49 @@ class VoteProgram {
|
|
|
9048
9343
|
data
|
|
9049
9344
|
});
|
|
9050
9345
|
}
|
|
9346
|
+
/**
|
|
9347
|
+
* Generate a transaction that authorizes a new Voter or Withdrawer on the Vote account
|
|
9348
|
+
* where the current Voter or Withdrawer authority is a derived key.
|
|
9349
|
+
*/
|
|
9350
|
+
|
|
9351
|
+
|
|
9352
|
+
static authorizeWithSeed(params) {
|
|
9353
|
+
const {
|
|
9354
|
+
currentAuthorityDerivedKeyBasePubkey,
|
|
9355
|
+
currentAuthorityDerivedKeyOwnerPubkey,
|
|
9356
|
+
currentAuthorityDerivedKeySeed,
|
|
9357
|
+
newAuthorizedPubkey,
|
|
9358
|
+
voteAuthorizationType,
|
|
9359
|
+
votePubkey
|
|
9360
|
+
} = params;
|
|
9361
|
+
const type = VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed;
|
|
9362
|
+
const data = encodeData(type, {
|
|
9363
|
+
voteAuthorizeWithSeedArgs: {
|
|
9364
|
+
currentAuthorityDerivedKeyOwnerPubkey: toBuffer(currentAuthorityDerivedKeyOwnerPubkey.toBuffer()),
|
|
9365
|
+
currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
|
|
9366
|
+
newAuthorized: toBuffer(newAuthorizedPubkey.toBuffer()),
|
|
9367
|
+
voteAuthorizationType: voteAuthorizationType.index
|
|
9368
|
+
}
|
|
9369
|
+
});
|
|
9370
|
+
const keys = [{
|
|
9371
|
+
pubkey: votePubkey,
|
|
9372
|
+
isSigner: false,
|
|
9373
|
+
isWritable: true
|
|
9374
|
+
}, {
|
|
9375
|
+
pubkey: SYSVAR_CLOCK_PUBKEY,
|
|
9376
|
+
isSigner: false,
|
|
9377
|
+
isWritable: false
|
|
9378
|
+
}, {
|
|
9379
|
+
pubkey: currentAuthorityDerivedKeyBasePubkey,
|
|
9380
|
+
isSigner: true,
|
|
9381
|
+
isWritable: false
|
|
9382
|
+
}];
|
|
9383
|
+
return new Transaction().add({
|
|
9384
|
+
keys,
|
|
9385
|
+
programId: this.programId,
|
|
9386
|
+
data
|
|
9387
|
+
});
|
|
9388
|
+
}
|
|
9051
9389
|
/**
|
|
9052
9390
|
* Generate a transaction to withdraw from a Vote account.
|
|
9053
9391
|
*/
|
|
@@ -9429,6 +9767,7 @@ exports.Transaction = Transaction;
|
|
|
9429
9767
|
exports.TransactionExpiredBlockheightExceededError = TransactionExpiredBlockheightExceededError;
|
|
9430
9768
|
exports.TransactionExpiredTimeoutError = TransactionExpiredTimeoutError;
|
|
9431
9769
|
exports.TransactionInstruction = TransactionInstruction;
|
|
9770
|
+
exports.TransactionMessage = TransactionMessage;
|
|
9432
9771
|
exports.VALIDATOR_INFO_KEY = VALIDATOR_INFO_KEY;
|
|
9433
9772
|
exports.VERSION_PREFIX_MASK = VERSION_PREFIX_MASK;
|
|
9434
9773
|
exports.VOTE_PROGRAM_ID = VOTE_PROGRAM_ID;
|