@solana/web3.js 1.56.2 → 1.59.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.browser.cjs.js +583 -16
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +582 -16
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +583 -16
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +3062 -2931
- package/lib/index.esm.js +582 -16
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +837 -714
- 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 +583 -16
- 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/account-keys.ts +79 -0
- package/src/message/compiled-keys.ts +165 -0
- package/src/message/index.ts +2 -0
- package/src/message/legacy.ts +34 -2
- package/src/message/v0.ts +137 -0
- package/src/programs/secp256k1.ts +5 -7
- package/src/programs/vote.ts +109 -2
- package/src/publickey.ts +12 -0
- package/src/transaction/index.ts +1 -0
- package/src/transaction/message.ts +147 -0
package/lib/index.browser.cjs.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
|
/**
|
|
@@ -143,12 +142,14 @@ const PUBLIC_KEY_LENGTH = 32;
|
|
|
143
142
|
|
|
144
143
|
function isPublicKeyData(value) {
|
|
145
144
|
return value._bn !== undefined;
|
|
146
|
-
}
|
|
145
|
+
} // local counter used by PublicKey.unique()
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
let uniquePublicKeyCounter = 1;
|
|
147
149
|
/**
|
|
148
150
|
* A public key
|
|
149
151
|
*/
|
|
150
152
|
|
|
151
|
-
|
|
152
153
|
class PublicKey extends Struct {
|
|
153
154
|
/** @internal */
|
|
154
155
|
|
|
@@ -181,6 +182,16 @@ class PublicKey extends Struct {
|
|
|
181
182
|
}
|
|
182
183
|
}
|
|
183
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Returns a unique PublicKey for tests and benchmarks using acounter
|
|
187
|
+
*/
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
static unique() {
|
|
191
|
+
const key = new PublicKey(uniquePublicKeyCounter);
|
|
192
|
+
uniquePublicKeyCounter += 1;
|
|
193
|
+
return new PublicKey(key.toBuffer());
|
|
194
|
+
}
|
|
184
195
|
/**
|
|
185
196
|
* Default public key value. (All zeros)
|
|
186
197
|
*/
|
|
@@ -437,10 +448,74 @@ Object.defineProperty(TransactionExpiredTimeoutError.prototype, 'name', {
|
|
|
437
448
|
value: 'TransactionExpiredTimeoutError'
|
|
438
449
|
});
|
|
439
450
|
|
|
451
|
+
class MessageAccountKeys {
|
|
452
|
+
constructor(staticAccountKeys, accountKeysFromLookups) {
|
|
453
|
+
this.staticAccountKeys = void 0;
|
|
454
|
+
this.accountKeysFromLookups = void 0;
|
|
455
|
+
this.staticAccountKeys = staticAccountKeys;
|
|
456
|
+
this.accountKeysFromLookups = accountKeysFromLookups;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
keySegments() {
|
|
460
|
+
const keySegments = [this.staticAccountKeys];
|
|
461
|
+
|
|
462
|
+
if (this.accountKeysFromLookups) {
|
|
463
|
+
keySegments.push(this.accountKeysFromLookups.writable);
|
|
464
|
+
keySegments.push(this.accountKeysFromLookups.readonly);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return keySegments;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
get(index) {
|
|
471
|
+
for (const keySegment of this.keySegments()) {
|
|
472
|
+
if (index < keySegment.length) {
|
|
473
|
+
return keySegment[index];
|
|
474
|
+
} else {
|
|
475
|
+
index -= keySegment.length;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
get length() {
|
|
483
|
+
return this.keySegments().flat().length;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
compileInstructions(instructions) {
|
|
487
|
+
// Bail early if any account indexes would overflow a u8
|
|
488
|
+
const U8_MAX = 255;
|
|
489
|
+
|
|
490
|
+
if (this.length > U8_MAX + 1) {
|
|
491
|
+
throw new Error('Account index overflow encountered during compilation');
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const keyIndexMap = new Map();
|
|
495
|
+
this.keySegments().flat().forEach((key, index) => {
|
|
496
|
+
keyIndexMap.set(key.toBase58(), index);
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
const findKeyIndex = key => {
|
|
500
|
+
const keyIndex = keyIndexMap.get(key.toBase58());
|
|
501
|
+
if (keyIndex === undefined) throw new Error('Encountered an unknown instruction account key during compilation');
|
|
502
|
+
return keyIndex;
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
return instructions.map(instruction => {
|
|
506
|
+
return {
|
|
507
|
+
programIdIndex: findKeyIndex(instruction.programId),
|
|
508
|
+
accountKeyIndexes: instruction.keys.map(meta => findKeyIndex(meta.pubkey)),
|
|
509
|
+
data: instruction.data
|
|
510
|
+
};
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
}
|
|
515
|
+
|
|
440
516
|
/**
|
|
441
517
|
* Layout for a public key
|
|
442
518
|
*/
|
|
443
|
-
|
|
444
519
|
const publicKey = (property = 'publicKey') => {
|
|
445
520
|
return BufferLayout__namespace.blob(32, property);
|
|
446
521
|
};
|
|
@@ -504,6 +579,13 @@ const lockup = (property = 'lockup') => {
|
|
|
504
579
|
const voteInit = (property = 'voteInit') => {
|
|
505
580
|
return BufferLayout__namespace.struct([publicKey('nodePubkey'), publicKey('authorizedVoter'), publicKey('authorizedWithdrawer'), BufferLayout__namespace.u8('commission')], property);
|
|
506
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
|
+
};
|
|
507
589
|
function getAlloc(type, fields) {
|
|
508
590
|
const getItemAlloc = item => {
|
|
509
591
|
if (item.span >= 0) {
|
|
@@ -516,6 +598,11 @@ function getAlloc(type, fields) {
|
|
|
516
598
|
if (Array.isArray(field)) {
|
|
517
599
|
return field.length * getItemAlloc(item.elementLayout);
|
|
518
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]);
|
|
519
606
|
} // Couldn't determine allocated size of layout
|
|
520
607
|
|
|
521
608
|
|
|
@@ -562,6 +649,129 @@ function encodeLength(bytes, len) {
|
|
|
562
649
|
}
|
|
563
650
|
}
|
|
564
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
|
+
|
|
565
775
|
/**
|
|
566
776
|
* List of instructions to be processed atomically
|
|
567
777
|
*/
|
|
@@ -599,6 +809,27 @@ class Message {
|
|
|
599
809
|
return [];
|
|
600
810
|
}
|
|
601
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
|
+
|
|
602
833
|
isAccountSigner(index) {
|
|
603
834
|
return index < this.header.numRequiredSignatures;
|
|
604
835
|
}
|
|
@@ -688,7 +919,7 @@ class Message {
|
|
|
688
919
|
for (let i = 0; i < accountCount; i++) {
|
|
689
920
|
const account = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
690
921
|
byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
|
|
691
|
-
accountKeys.push(
|
|
922
|
+
accountKeys.push(new PublicKey(buffer.Buffer.from(account)));
|
|
692
923
|
}
|
|
693
924
|
|
|
694
925
|
const recentBlockhash = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
@@ -727,12 +958,6 @@ class Message {
|
|
|
727
958
|
|
|
728
959
|
}
|
|
729
960
|
|
|
730
|
-
function assert (condition, message) {
|
|
731
|
-
if (!condition) {
|
|
732
|
-
throw new Error(message || 'Assertion failed');
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
|
|
736
961
|
/**
|
|
737
962
|
* Message constructor arguments
|
|
738
963
|
*/
|
|
@@ -755,6 +980,102 @@ class MessageV0 {
|
|
|
755
980
|
return 0;
|
|
756
981
|
}
|
|
757
982
|
|
|
983
|
+
get numAccountKeysFromLookups() {
|
|
984
|
+
let count = 0;
|
|
985
|
+
|
|
986
|
+
for (const lookup of this.addressTableLookups) {
|
|
987
|
+
count += lookup.readonlyIndexes.length + lookup.writableIndexes.length;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
return count;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
getAccountKeys(args) {
|
|
994
|
+
let accountKeysFromLookups;
|
|
995
|
+
|
|
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
|
+
}
|
|
1000
|
+
|
|
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');
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
return new MessageAccountKeys(this.staticAccountKeys, accountKeysFromLookups);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
resolveAddressTableLookups(addressLookupTableAccounts) {
|
|
1012
|
+
const accountKeysFromLookups = {
|
|
1013
|
+
writable: [],
|
|
1014
|
+
readonly: []
|
|
1015
|
+
};
|
|
1016
|
+
|
|
1017
|
+
for (const tableLookup of this.addressTableLookups) {
|
|
1018
|
+
const tableAccount = addressLookupTableAccounts.find(account => account.key.equals(tableLookup.accountKey));
|
|
1019
|
+
|
|
1020
|
+
if (!tableAccount) {
|
|
1021
|
+
throw new Error(`Failed to find address lookup table account for table key ${tableLookup.accountKey.toBase58()}`);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
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()}`);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
|
|
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
|
+
}
|
|
1040
|
+
|
|
1041
|
+
return accountKeysFromLookups;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
static compile(args) {
|
|
1045
|
+
const compiledKeys = CompiledKeys.compile(args.instructions, args.payerKey);
|
|
1046
|
+
const addressTableLookups = new Array();
|
|
1047
|
+
const accountKeysFromLookups = {
|
|
1048
|
+
writable: new Array(),
|
|
1049
|
+
readonly: new Array()
|
|
1050
|
+
};
|
|
1051
|
+
const lookupTableAccounts = args.addressLookupTableAccounts || [];
|
|
1052
|
+
|
|
1053
|
+
for (const lookupTable of lookupTableAccounts) {
|
|
1054
|
+
const extractResult = compiledKeys.extractTableLookup(lookupTable);
|
|
1055
|
+
|
|
1056
|
+
if (extractResult !== undefined) {
|
|
1057
|
+
const [addressTableLookup, {
|
|
1058
|
+
writable,
|
|
1059
|
+
readonly
|
|
1060
|
+
}] = extractResult;
|
|
1061
|
+
addressTableLookups.push(addressTableLookup);
|
|
1062
|
+
accountKeysFromLookups.writable.push(...writable);
|
|
1063
|
+
accountKeysFromLookups.readonly.push(...readonly);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
const [header, staticAccountKeys] = compiledKeys.getMessageComponents();
|
|
1068
|
+
const accountKeys = new MessageAccountKeys(staticAccountKeys, accountKeysFromLookups);
|
|
1069
|
+
const compiledInstructions = accountKeys.compileInstructions(args.instructions);
|
|
1070
|
+
return new MessageV0({
|
|
1071
|
+
header,
|
|
1072
|
+
staticAccountKeys,
|
|
1073
|
+
recentBlockhash: args.recentBlockhash,
|
|
1074
|
+
compiledInstructions,
|
|
1075
|
+
addressTableLookups
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
|
|
758
1079
|
serialize() {
|
|
759
1080
|
const encodedStaticAccountKeysLength = Array();
|
|
760
1081
|
encodeLength(encodedStaticAccountKeysLength, this.staticAccountKeys.length);
|
|
@@ -1649,6 +1970,114 @@ class Transaction {
|
|
|
1649
1970
|
|
|
1650
1971
|
}
|
|
1651
1972
|
|
|
1973
|
+
class TransactionMessage {
|
|
1974
|
+
constructor(args) {
|
|
1975
|
+
this.accountKeys = void 0;
|
|
1976
|
+
this.instructions = void 0;
|
|
1977
|
+
this.recentBlockhash = void 0;
|
|
1978
|
+
this.accountKeys = args.accountKeys;
|
|
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 instructions = [];
|
|
2000
|
+
|
|
2001
|
+
for (const compiledIx of compiledInstructions) {
|
|
2002
|
+
const keys = [];
|
|
2003
|
+
|
|
2004
|
+
for (const keyIndex of compiledIx.accountKeyIndexes) {
|
|
2005
|
+
const pubkey = accountKeys.get(keyIndex);
|
|
2006
|
+
|
|
2007
|
+
if (pubkey === undefined) {
|
|
2008
|
+
throw new Error(`Failed to find key for account key index ${keyIndex}`);
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
const isSigner = keyIndex < numRequiredSignatures;
|
|
2012
|
+
let isWritable;
|
|
2013
|
+
|
|
2014
|
+
if (isSigner) {
|
|
2015
|
+
isWritable = keyIndex < numWritableSignedAccounts;
|
|
2016
|
+
} else if (keyIndex < accountKeys.staticAccountKeys.length) {
|
|
2017
|
+
isWritable = keyIndex - numRequiredSignatures < numWritableUnsignedAccounts;
|
|
2018
|
+
} else {
|
|
2019
|
+
isWritable = keyIndex - accountKeys.staticAccountKeys.length < // accountKeysFromLookups cannot be undefined because we already found a pubkey for this index above
|
|
2020
|
+
accountKeys.accountKeysFromLookups.writable.length;
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
keys.push({
|
|
2024
|
+
pubkey,
|
|
2025
|
+
isSigner: keyIndex < header.numRequiredSignatures,
|
|
2026
|
+
isWritable
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
const programId = accountKeys.get(compiledIx.programIdIndex);
|
|
2031
|
+
|
|
2032
|
+
if (programId === undefined) {
|
|
2033
|
+
throw new Error(`Failed to find program id for program id index ${compiledIx.programIdIndex}`);
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
instructions.push(new TransactionInstruction({
|
|
2037
|
+
programId,
|
|
2038
|
+
data: toBuffer(compiledIx.data),
|
|
2039
|
+
keys
|
|
2040
|
+
}));
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
return new TransactionMessage({
|
|
2044
|
+
accountKeys,
|
|
2045
|
+
instructions,
|
|
2046
|
+
recentBlockhash
|
|
2047
|
+
});
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
compileToLegacyMessage() {
|
|
2051
|
+
const payerKey = this.accountKeys.get(0);
|
|
2052
|
+
|
|
2053
|
+
if (payerKey === undefined) {
|
|
2054
|
+
throw new Error('Failed to compile message because no account keys were found');
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2057
|
+
return Message.compile({
|
|
2058
|
+
payerKey,
|
|
2059
|
+
recentBlockhash: this.recentBlockhash,
|
|
2060
|
+
instructions: this.instructions
|
|
2061
|
+
});
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
compileToV0Message(addressLookupTableAccounts) {
|
|
2065
|
+
const payerKey = this.accountKeys.get(0);
|
|
2066
|
+
|
|
2067
|
+
if (payerKey === undefined) {
|
|
2068
|
+
throw new Error('Failed to compile message because no account keys were found');
|
|
2069
|
+
}
|
|
2070
|
+
|
|
2071
|
+
return MessageV0.compile({
|
|
2072
|
+
payerKey,
|
|
2073
|
+
recentBlockhash: this.recentBlockhash,
|
|
2074
|
+
instructions: this.instructions,
|
|
2075
|
+
addressLookupTableAccounts
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
}
|
|
2080
|
+
|
|
1652
2081
|
/**
|
|
1653
2082
|
* Versioned transaction class
|
|
1654
2083
|
*/
|
|
@@ -5952,10 +6381,44 @@ class Connection {
|
|
|
5952
6381
|
}
|
|
5953
6382
|
/**
|
|
5954
6383
|
* Simulate a transaction
|
|
6384
|
+
*
|
|
6385
|
+
* @deprecated Instead, call {@link simulateTransaction} with {@link
|
|
6386
|
+
* VersionedTransaction} and {@link SimulateTransactionConfig} parameters
|
|
5955
6387
|
*/
|
|
5956
6388
|
|
|
5957
6389
|
|
|
5958
|
-
|
|
6390
|
+
/**
|
|
6391
|
+
* Simulate a transaction
|
|
6392
|
+
*/
|
|
6393
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
6394
|
+
async simulateTransaction(transactionOrMessage, configOrSigners, includeAccounts) {
|
|
6395
|
+
if ('message' in transactionOrMessage) {
|
|
6396
|
+
const versionedTx = transactionOrMessage;
|
|
6397
|
+
const wireTransaction = versionedTx.serialize();
|
|
6398
|
+
const encodedTransaction = buffer.Buffer.from(wireTransaction).toString('base64');
|
|
6399
|
+
|
|
6400
|
+
if (Array.isArray(configOrSigners) || includeAccounts !== undefined) {
|
|
6401
|
+
throw new Error('Invalid arguments');
|
|
6402
|
+
}
|
|
6403
|
+
|
|
6404
|
+
const config = configOrSigners || {};
|
|
6405
|
+
config.encoding = 'base64';
|
|
6406
|
+
|
|
6407
|
+
if (!('commitment' in config)) {
|
|
6408
|
+
config.commitment = this.commitment;
|
|
6409
|
+
}
|
|
6410
|
+
|
|
6411
|
+
const args = [encodedTransaction, config];
|
|
6412
|
+
const unsafeRes = await this._rpcRequest('simulateTransaction', args);
|
|
6413
|
+
const res = superstruct.create(unsafeRes, SimulatedTransactionResponseStruct);
|
|
6414
|
+
|
|
6415
|
+
if ('error' in res) {
|
|
6416
|
+
throw new Error('failed to simulate transaction: ' + res.error.message);
|
|
6417
|
+
}
|
|
6418
|
+
|
|
6419
|
+
return res.result;
|
|
6420
|
+
}
|
|
6421
|
+
|
|
5959
6422
|
let transaction;
|
|
5960
6423
|
|
|
5961
6424
|
if (transactionOrMessage instanceof Transaction) {
|
|
@@ -5971,6 +6434,12 @@ class Connection {
|
|
|
5971
6434
|
transaction._message = transaction._json = undefined;
|
|
5972
6435
|
}
|
|
5973
6436
|
|
|
6437
|
+
if (configOrSigners !== undefined && !Array.isArray(configOrSigners)) {
|
|
6438
|
+
throw new Error('Invalid arguments');
|
|
6439
|
+
}
|
|
6440
|
+
|
|
6441
|
+
const signers = configOrSigners;
|
|
6442
|
+
|
|
5974
6443
|
if (transaction.nonceInfo && signers) {
|
|
5975
6444
|
transaction.sign(...signers);
|
|
5976
6445
|
} else {
|
|
@@ -6053,10 +6522,32 @@ class Connection {
|
|
|
6053
6522
|
}
|
|
6054
6523
|
/**
|
|
6055
6524
|
* Sign and send a transaction
|
|
6525
|
+
*
|
|
6526
|
+
* @deprecated Instead, call {@link sendTransaction} with a {@link
|
|
6527
|
+
* VersionedTransaction}
|
|
6056
6528
|
*/
|
|
6057
6529
|
|
|
6058
6530
|
|
|
6059
|
-
|
|
6531
|
+
/**
|
|
6532
|
+
* Sign and send a transaction
|
|
6533
|
+
*/
|
|
6534
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
6535
|
+
async sendTransaction(transaction, signersOrOptions, options) {
|
|
6536
|
+
if ('message' in transaction) {
|
|
6537
|
+
if (signersOrOptions && Array.isArray(signersOrOptions)) {
|
|
6538
|
+
throw new Error('Invalid arguments');
|
|
6539
|
+
}
|
|
6540
|
+
|
|
6541
|
+
const wireTransaction = transaction.serialize();
|
|
6542
|
+
return await this.sendRawTransaction(wireTransaction, options);
|
|
6543
|
+
}
|
|
6544
|
+
|
|
6545
|
+
if (signersOrOptions === undefined || !Array.isArray(signersOrOptions)) {
|
|
6546
|
+
throw new Error('Invalid arguments');
|
|
6547
|
+
}
|
|
6548
|
+
|
|
6549
|
+
const signers = signersOrOptions;
|
|
6550
|
+
|
|
6060
6551
|
if (transaction.nonceInfo) {
|
|
6061
6552
|
transaction.sign(...signers);
|
|
6062
6553
|
} else {
|
|
@@ -7583,7 +8074,7 @@ class Secp256k1Program {
|
|
|
7583
8074
|
assert(publicKey.length === PUBLIC_KEY_BYTES, `Public key must be ${PUBLIC_KEY_BYTES} bytes but received ${publicKey.length} bytes`);
|
|
7584
8075
|
|
|
7585
8076
|
try {
|
|
7586
|
-
return buffer.Buffer.from(
|
|
8077
|
+
return buffer.Buffer.from(sha3.keccak_256(toBuffer(publicKey))).slice(-ETHEREUM_ADDRESS_BYTES);
|
|
7587
8078
|
} catch (error) {
|
|
7588
8079
|
throw new Error(`Error constructing Ethereum address: ${error}`);
|
|
7589
8080
|
}
|
|
@@ -7683,7 +8174,7 @@ class Secp256k1Program {
|
|
|
7683
8174
|
/* isCompressed */
|
|
7684
8175
|
).slice(1); // throw away leading byte
|
|
7685
8176
|
|
|
7686
|
-
const messageHash = buffer.Buffer.from(
|
|
8177
|
+
const messageHash = buffer.Buffer.from(sha3.keccak_256(toBuffer(message)));
|
|
7687
8178
|
const [signature, recoveryId] = ecdsaSign(messageHash, privateKey);
|
|
7688
8179
|
return this.createInstructionWithPublicKey({
|
|
7689
8180
|
publicKey,
|
|
@@ -8577,6 +9068,33 @@ class VoteInstruction {
|
|
|
8577
9068
|
}
|
|
8578
9069
|
};
|
|
8579
9070
|
}
|
|
9071
|
+
/**
|
|
9072
|
+
* Decode an authorize instruction and retrieve the instruction params.
|
|
9073
|
+
*/
|
|
9074
|
+
|
|
9075
|
+
|
|
9076
|
+
static decodeAuthorizeWithSeed(instruction) {
|
|
9077
|
+
this.checkProgramId(instruction.programId);
|
|
9078
|
+
this.checkKeyLength(instruction.keys, 3);
|
|
9079
|
+
const {
|
|
9080
|
+
voteAuthorizeWithSeedArgs: {
|
|
9081
|
+
currentAuthorityDerivedKeyOwnerPubkey,
|
|
9082
|
+
currentAuthorityDerivedKeySeed,
|
|
9083
|
+
newAuthorized,
|
|
9084
|
+
voteAuthorizationType
|
|
9085
|
+
}
|
|
9086
|
+
} = decodeData$1(VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed, instruction.data);
|
|
9087
|
+
return {
|
|
9088
|
+
currentAuthorityDerivedKeyBasePubkey: instruction.keys[2].pubkey,
|
|
9089
|
+
currentAuthorityDerivedKeyOwnerPubkey: new PublicKey(currentAuthorityDerivedKeyOwnerPubkey),
|
|
9090
|
+
currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
|
|
9091
|
+
newAuthorizedPubkey: new PublicKey(newAuthorized),
|
|
9092
|
+
voteAuthorizationType: {
|
|
9093
|
+
index: voteAuthorizationType
|
|
9094
|
+
},
|
|
9095
|
+
votePubkey: instruction.keys[0].pubkey
|
|
9096
|
+
};
|
|
9097
|
+
}
|
|
8580
9098
|
/**
|
|
8581
9099
|
* Decode a withdraw instruction and retrieve the instruction params.
|
|
8582
9100
|
*/
|
|
@@ -8633,6 +9151,10 @@ const VOTE_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
|
8633
9151
|
Withdraw: {
|
|
8634
9152
|
index: 3,
|
|
8635
9153
|
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), BufferLayout__namespace.ns64('lamports')])
|
|
9154
|
+
},
|
|
9155
|
+
AuthorizeWithSeed: {
|
|
9156
|
+
index: 10,
|
|
9157
|
+
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), voteAuthorizeWithSeedArgs()])
|
|
8636
9158
|
}
|
|
8637
9159
|
});
|
|
8638
9160
|
/**
|
|
@@ -8761,6 +9283,49 @@ class VoteProgram {
|
|
|
8761
9283
|
data
|
|
8762
9284
|
});
|
|
8763
9285
|
}
|
|
9286
|
+
/**
|
|
9287
|
+
* Generate a transaction that authorizes a new Voter or Withdrawer on the Vote account
|
|
9288
|
+
* where the current Voter or Withdrawer authority is a derived key.
|
|
9289
|
+
*/
|
|
9290
|
+
|
|
9291
|
+
|
|
9292
|
+
static authorizeWithSeed(params) {
|
|
9293
|
+
const {
|
|
9294
|
+
currentAuthorityDerivedKeyBasePubkey,
|
|
9295
|
+
currentAuthorityDerivedKeyOwnerPubkey,
|
|
9296
|
+
currentAuthorityDerivedKeySeed,
|
|
9297
|
+
newAuthorizedPubkey,
|
|
9298
|
+
voteAuthorizationType,
|
|
9299
|
+
votePubkey
|
|
9300
|
+
} = params;
|
|
9301
|
+
const type = VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed;
|
|
9302
|
+
const data = encodeData(type, {
|
|
9303
|
+
voteAuthorizeWithSeedArgs: {
|
|
9304
|
+
currentAuthorityDerivedKeyOwnerPubkey: toBuffer(currentAuthorityDerivedKeyOwnerPubkey.toBuffer()),
|
|
9305
|
+
currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
|
|
9306
|
+
newAuthorized: toBuffer(newAuthorizedPubkey.toBuffer()),
|
|
9307
|
+
voteAuthorizationType: voteAuthorizationType.index
|
|
9308
|
+
}
|
|
9309
|
+
});
|
|
9310
|
+
const keys = [{
|
|
9311
|
+
pubkey: votePubkey,
|
|
9312
|
+
isSigner: false,
|
|
9313
|
+
isWritable: true
|
|
9314
|
+
}, {
|
|
9315
|
+
pubkey: SYSVAR_CLOCK_PUBKEY,
|
|
9316
|
+
isSigner: false,
|
|
9317
|
+
isWritable: false
|
|
9318
|
+
}, {
|
|
9319
|
+
pubkey: currentAuthorityDerivedKeyBasePubkey,
|
|
9320
|
+
isSigner: true,
|
|
9321
|
+
isWritable: false
|
|
9322
|
+
}];
|
|
9323
|
+
return new Transaction().add({
|
|
9324
|
+
keys,
|
|
9325
|
+
programId: this.programId,
|
|
9326
|
+
data
|
|
9327
|
+
});
|
|
9328
|
+
}
|
|
8764
9329
|
/**
|
|
8765
9330
|
* Generate a transaction to withdraw from a Vote account.
|
|
8766
9331
|
*/
|
|
@@ -9107,6 +9672,7 @@ exports.Loader = Loader;
|
|
|
9107
9672
|
exports.Lockup = Lockup;
|
|
9108
9673
|
exports.MAX_SEED_LENGTH = MAX_SEED_LENGTH;
|
|
9109
9674
|
exports.Message = Message;
|
|
9675
|
+
exports.MessageAccountKeys = MessageAccountKeys;
|
|
9110
9676
|
exports.MessageV0 = MessageV0;
|
|
9111
9677
|
exports.NONCE_ACCOUNT_LENGTH = NONCE_ACCOUNT_LENGTH;
|
|
9112
9678
|
exports.NonceAccount = NonceAccount;
|
|
@@ -9141,6 +9707,7 @@ exports.Transaction = Transaction;
|
|
|
9141
9707
|
exports.TransactionExpiredBlockheightExceededError = TransactionExpiredBlockheightExceededError;
|
|
9142
9708
|
exports.TransactionExpiredTimeoutError = TransactionExpiredTimeoutError;
|
|
9143
9709
|
exports.TransactionInstruction = TransactionInstruction;
|
|
9710
|
+
exports.TransactionMessage = TransactionMessage;
|
|
9144
9711
|
exports.VALIDATOR_INFO_KEY = VALIDATOR_INFO_KEY;
|
|
9145
9712
|
exports.VERSION_PREFIX_MASK = VERSION_PREFIX_MASK;
|
|
9146
9713
|
exports.VOTE_PROGRAM_ID = VOTE_PROGRAM_ID;
|