@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.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
|
/**
|
|
@@ -149,12 +148,14 @@ const PUBLIC_KEY_LENGTH = 32;
|
|
|
149
148
|
|
|
150
149
|
function isPublicKeyData(value) {
|
|
151
150
|
return value._bn !== undefined;
|
|
152
|
-
}
|
|
151
|
+
} // local counter used by PublicKey.unique()
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
let uniquePublicKeyCounter = 1;
|
|
153
155
|
/**
|
|
154
156
|
* A public key
|
|
155
157
|
*/
|
|
156
158
|
|
|
157
|
-
|
|
158
159
|
class PublicKey extends Struct {
|
|
159
160
|
/** @internal */
|
|
160
161
|
|
|
@@ -187,6 +188,16 @@ class PublicKey extends Struct {
|
|
|
187
188
|
}
|
|
188
189
|
}
|
|
189
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Returns a unique PublicKey for tests and benchmarks using acounter
|
|
193
|
+
*/
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
static unique() {
|
|
197
|
+
const key = new PublicKey(uniquePublicKeyCounter);
|
|
198
|
+
uniquePublicKeyCounter += 1;
|
|
199
|
+
return new PublicKey(key.toBuffer());
|
|
200
|
+
}
|
|
190
201
|
/**
|
|
191
202
|
* Default public key value. (All zeros)
|
|
192
203
|
*/
|
|
@@ -443,10 +454,74 @@ Object.defineProperty(TransactionExpiredTimeoutError.prototype, 'name', {
|
|
|
443
454
|
value: 'TransactionExpiredTimeoutError'
|
|
444
455
|
});
|
|
445
456
|
|
|
457
|
+
class MessageAccountKeys {
|
|
458
|
+
constructor(staticAccountKeys, accountKeysFromLookups) {
|
|
459
|
+
this.staticAccountKeys = void 0;
|
|
460
|
+
this.accountKeysFromLookups = void 0;
|
|
461
|
+
this.staticAccountKeys = staticAccountKeys;
|
|
462
|
+
this.accountKeysFromLookups = accountKeysFromLookups;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
keySegments() {
|
|
466
|
+
const keySegments = [this.staticAccountKeys];
|
|
467
|
+
|
|
468
|
+
if (this.accountKeysFromLookups) {
|
|
469
|
+
keySegments.push(this.accountKeysFromLookups.writable);
|
|
470
|
+
keySegments.push(this.accountKeysFromLookups.readonly);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
return keySegments;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
get(index) {
|
|
477
|
+
for (const keySegment of this.keySegments()) {
|
|
478
|
+
if (index < keySegment.length) {
|
|
479
|
+
return keySegment[index];
|
|
480
|
+
} else {
|
|
481
|
+
index -= keySegment.length;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
get length() {
|
|
489
|
+
return this.keySegments().flat().length;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
compileInstructions(instructions) {
|
|
493
|
+
// Bail early if any account indexes would overflow a u8
|
|
494
|
+
const U8_MAX = 255;
|
|
495
|
+
|
|
496
|
+
if (this.length > U8_MAX + 1) {
|
|
497
|
+
throw new Error('Account index overflow encountered during compilation');
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
const keyIndexMap = new Map();
|
|
501
|
+
this.keySegments().flat().forEach((key, index) => {
|
|
502
|
+
keyIndexMap.set(key.toBase58(), index);
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
const findKeyIndex = key => {
|
|
506
|
+
const keyIndex = keyIndexMap.get(key.toBase58());
|
|
507
|
+
if (keyIndex === undefined) throw new Error('Encountered an unknown instruction account key during compilation');
|
|
508
|
+
return keyIndex;
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
return instructions.map(instruction => {
|
|
512
|
+
return {
|
|
513
|
+
programIdIndex: findKeyIndex(instruction.programId),
|
|
514
|
+
accountKeyIndexes: instruction.keys.map(meta => findKeyIndex(meta.pubkey)),
|
|
515
|
+
data: instruction.data
|
|
516
|
+
};
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
}
|
|
521
|
+
|
|
446
522
|
/**
|
|
447
523
|
* Layout for a public key
|
|
448
524
|
*/
|
|
449
|
-
|
|
450
525
|
const publicKey = (property = 'publicKey') => {
|
|
451
526
|
return BufferLayout__namespace.blob(32, property);
|
|
452
527
|
};
|
|
@@ -510,6 +585,13 @@ const lockup = (property = 'lockup') => {
|
|
|
510
585
|
const voteInit = (property = 'voteInit') => {
|
|
511
586
|
return BufferLayout__namespace.struct([publicKey('nodePubkey'), publicKey('authorizedVoter'), publicKey('authorizedWithdrawer'), BufferLayout__namespace.u8('commission')], property);
|
|
512
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
|
+
};
|
|
513
595
|
function getAlloc(type, fields) {
|
|
514
596
|
const getItemAlloc = item => {
|
|
515
597
|
if (item.span >= 0) {
|
|
@@ -522,6 +604,11 @@ function getAlloc(type, fields) {
|
|
|
522
604
|
if (Array.isArray(field)) {
|
|
523
605
|
return field.length * getItemAlloc(item.elementLayout);
|
|
524
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]);
|
|
525
612
|
} // Couldn't determine allocated size of layout
|
|
526
613
|
|
|
527
614
|
|
|
@@ -568,6 +655,129 @@ function encodeLength(bytes, len) {
|
|
|
568
655
|
}
|
|
569
656
|
}
|
|
570
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
|
+
|
|
571
781
|
/**
|
|
572
782
|
* List of instructions to be processed atomically
|
|
573
783
|
*/
|
|
@@ -605,6 +815,27 @@ class Message {
|
|
|
605
815
|
return [];
|
|
606
816
|
}
|
|
607
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
|
+
|
|
608
839
|
isAccountSigner(index) {
|
|
609
840
|
return index < this.header.numRequiredSignatures;
|
|
610
841
|
}
|
|
@@ -694,7 +925,7 @@ class Message {
|
|
|
694
925
|
for (let i = 0; i < accountCount; i++) {
|
|
695
926
|
const account = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
696
927
|
byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
|
|
697
|
-
accountKeys.push(
|
|
928
|
+
accountKeys.push(new PublicKey(buffer.Buffer.from(account)));
|
|
698
929
|
}
|
|
699
930
|
|
|
700
931
|
const recentBlockhash = byteArray.slice(0, PUBLIC_KEY_LENGTH);
|
|
@@ -733,12 +964,6 @@ class Message {
|
|
|
733
964
|
|
|
734
965
|
}
|
|
735
966
|
|
|
736
|
-
function assert (condition, message) {
|
|
737
|
-
if (!condition) {
|
|
738
|
-
throw new Error(message || 'Assertion failed');
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
|
|
742
967
|
/**
|
|
743
968
|
* Message constructor arguments
|
|
744
969
|
*/
|
|
@@ -761,6 +986,102 @@ class MessageV0 {
|
|
|
761
986
|
return 0;
|
|
762
987
|
}
|
|
763
988
|
|
|
989
|
+
get numAccountKeysFromLookups() {
|
|
990
|
+
let count = 0;
|
|
991
|
+
|
|
992
|
+
for (const lookup of this.addressTableLookups) {
|
|
993
|
+
count += lookup.readonlyIndexes.length + lookup.writableIndexes.length;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
return count;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
getAccountKeys(args) {
|
|
1000
|
+
let accountKeysFromLookups;
|
|
1001
|
+
|
|
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
|
+
}
|
|
1006
|
+
|
|
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');
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
return new MessageAccountKeys(this.staticAccountKeys, accountKeysFromLookups);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
resolveAddressTableLookups(addressLookupTableAccounts) {
|
|
1018
|
+
const accountKeysFromLookups = {
|
|
1019
|
+
writable: [],
|
|
1020
|
+
readonly: []
|
|
1021
|
+
};
|
|
1022
|
+
|
|
1023
|
+
for (const tableLookup of this.addressTableLookups) {
|
|
1024
|
+
const tableAccount = addressLookupTableAccounts.find(account => account.key.equals(tableLookup.accountKey));
|
|
1025
|
+
|
|
1026
|
+
if (!tableAccount) {
|
|
1027
|
+
throw new Error(`Failed to find address lookup table account for table key ${tableLookup.accountKey.toBase58()}`);
|
|
1028
|
+
}
|
|
1029
|
+
|
|
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()}`);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
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
|
+
}
|
|
1046
|
+
|
|
1047
|
+
return accountKeysFromLookups;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
static compile(args) {
|
|
1051
|
+
const compiledKeys = CompiledKeys.compile(args.instructions, args.payerKey);
|
|
1052
|
+
const addressTableLookups = new Array();
|
|
1053
|
+
const accountKeysFromLookups = {
|
|
1054
|
+
writable: new Array(),
|
|
1055
|
+
readonly: new Array()
|
|
1056
|
+
};
|
|
1057
|
+
const lookupTableAccounts = args.addressLookupTableAccounts || [];
|
|
1058
|
+
|
|
1059
|
+
for (const lookupTable of lookupTableAccounts) {
|
|
1060
|
+
const extractResult = compiledKeys.extractTableLookup(lookupTable);
|
|
1061
|
+
|
|
1062
|
+
if (extractResult !== undefined) {
|
|
1063
|
+
const [addressTableLookup, {
|
|
1064
|
+
writable,
|
|
1065
|
+
readonly
|
|
1066
|
+
}] = extractResult;
|
|
1067
|
+
addressTableLookups.push(addressTableLookup);
|
|
1068
|
+
accountKeysFromLookups.writable.push(...writable);
|
|
1069
|
+
accountKeysFromLookups.readonly.push(...readonly);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
const [header, staticAccountKeys] = compiledKeys.getMessageComponents();
|
|
1074
|
+
const accountKeys = new MessageAccountKeys(staticAccountKeys, accountKeysFromLookups);
|
|
1075
|
+
const compiledInstructions = accountKeys.compileInstructions(args.instructions);
|
|
1076
|
+
return new MessageV0({
|
|
1077
|
+
header,
|
|
1078
|
+
staticAccountKeys,
|
|
1079
|
+
recentBlockhash: args.recentBlockhash,
|
|
1080
|
+
compiledInstructions,
|
|
1081
|
+
addressTableLookups
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
|
|
764
1085
|
serialize() {
|
|
765
1086
|
const encodedStaticAccountKeysLength = Array();
|
|
766
1087
|
encodeLength(encodedStaticAccountKeysLength, this.staticAccountKeys.length);
|
|
@@ -1655,6 +1976,114 @@ class Transaction {
|
|
|
1655
1976
|
|
|
1656
1977
|
}
|
|
1657
1978
|
|
|
1979
|
+
class TransactionMessage {
|
|
1980
|
+
constructor(args) {
|
|
1981
|
+
this.accountKeys = void 0;
|
|
1982
|
+
this.instructions = void 0;
|
|
1983
|
+
this.recentBlockhash = void 0;
|
|
1984
|
+
this.accountKeys = args.accountKeys;
|
|
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 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
|
+
accountKeys,
|
|
2051
|
+
instructions,
|
|
2052
|
+
recentBlockhash
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
compileToLegacyMessage() {
|
|
2057
|
+
const payerKey = this.accountKeys.get(0);
|
|
2058
|
+
|
|
2059
|
+
if (payerKey === undefined) {
|
|
2060
|
+
throw new Error('Failed to compile message because no account keys were found');
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
return Message.compile({
|
|
2064
|
+
payerKey,
|
|
2065
|
+
recentBlockhash: this.recentBlockhash,
|
|
2066
|
+
instructions: this.instructions
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
compileToV0Message(addressLookupTableAccounts) {
|
|
2071
|
+
const payerKey = this.accountKeys.get(0);
|
|
2072
|
+
|
|
2073
|
+
if (payerKey === undefined) {
|
|
2074
|
+
throw new Error('Failed to compile message because no account keys were found');
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
return MessageV0.compile({
|
|
2078
|
+
payerKey,
|
|
2079
|
+
recentBlockhash: this.recentBlockhash,
|
|
2080
|
+
instructions: this.instructions,
|
|
2081
|
+
addressLookupTableAccounts
|
|
2082
|
+
});
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
}
|
|
2086
|
+
|
|
1658
2087
|
/**
|
|
1659
2088
|
* Versioned transaction class
|
|
1660
2089
|
*/
|
|
@@ -6018,10 +6447,44 @@ class Connection {
|
|
|
6018
6447
|
}
|
|
6019
6448
|
/**
|
|
6020
6449
|
* Simulate a transaction
|
|
6450
|
+
*
|
|
6451
|
+
* @deprecated Instead, call {@link simulateTransaction} with {@link
|
|
6452
|
+
* VersionedTransaction} and {@link SimulateTransactionConfig} parameters
|
|
6021
6453
|
*/
|
|
6022
6454
|
|
|
6023
6455
|
|
|
6024
|
-
|
|
6456
|
+
/**
|
|
6457
|
+
* Simulate a transaction
|
|
6458
|
+
*/
|
|
6459
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
6460
|
+
async simulateTransaction(transactionOrMessage, configOrSigners, includeAccounts) {
|
|
6461
|
+
if ('message' in transactionOrMessage) {
|
|
6462
|
+
const versionedTx = transactionOrMessage;
|
|
6463
|
+
const wireTransaction = versionedTx.serialize();
|
|
6464
|
+
const encodedTransaction = buffer.Buffer.from(wireTransaction).toString('base64');
|
|
6465
|
+
|
|
6466
|
+
if (Array.isArray(configOrSigners) || includeAccounts !== undefined) {
|
|
6467
|
+
throw new Error('Invalid arguments');
|
|
6468
|
+
}
|
|
6469
|
+
|
|
6470
|
+
const config = configOrSigners || {};
|
|
6471
|
+
config.encoding = 'base64';
|
|
6472
|
+
|
|
6473
|
+
if (!('commitment' in config)) {
|
|
6474
|
+
config.commitment = this.commitment;
|
|
6475
|
+
}
|
|
6476
|
+
|
|
6477
|
+
const args = [encodedTransaction, config];
|
|
6478
|
+
const unsafeRes = await this._rpcRequest('simulateTransaction', args);
|
|
6479
|
+
const res = superstruct.create(unsafeRes, SimulatedTransactionResponseStruct);
|
|
6480
|
+
|
|
6481
|
+
if ('error' in res) {
|
|
6482
|
+
throw new Error('failed to simulate transaction: ' + res.error.message);
|
|
6483
|
+
}
|
|
6484
|
+
|
|
6485
|
+
return res.result;
|
|
6486
|
+
}
|
|
6487
|
+
|
|
6025
6488
|
let transaction;
|
|
6026
6489
|
|
|
6027
6490
|
if (transactionOrMessage instanceof Transaction) {
|
|
@@ -6037,6 +6500,12 @@ class Connection {
|
|
|
6037
6500
|
transaction._message = transaction._json = undefined;
|
|
6038
6501
|
}
|
|
6039
6502
|
|
|
6503
|
+
if (configOrSigners !== undefined && !Array.isArray(configOrSigners)) {
|
|
6504
|
+
throw new Error('Invalid arguments');
|
|
6505
|
+
}
|
|
6506
|
+
|
|
6507
|
+
const signers = configOrSigners;
|
|
6508
|
+
|
|
6040
6509
|
if (transaction.nonceInfo && signers) {
|
|
6041
6510
|
transaction.sign(...signers);
|
|
6042
6511
|
} else {
|
|
@@ -6119,10 +6588,32 @@ class Connection {
|
|
|
6119
6588
|
}
|
|
6120
6589
|
/**
|
|
6121
6590
|
* Sign and send a transaction
|
|
6591
|
+
*
|
|
6592
|
+
* @deprecated Instead, call {@link sendTransaction} with a {@link
|
|
6593
|
+
* VersionedTransaction}
|
|
6122
6594
|
*/
|
|
6123
6595
|
|
|
6124
6596
|
|
|
6125
|
-
|
|
6597
|
+
/**
|
|
6598
|
+
* Sign and send a transaction
|
|
6599
|
+
*/
|
|
6600
|
+
// eslint-disable-next-line no-dupe-class-members
|
|
6601
|
+
async sendTransaction(transaction, signersOrOptions, options) {
|
|
6602
|
+
if ('message' in transaction) {
|
|
6603
|
+
if (signersOrOptions && Array.isArray(signersOrOptions)) {
|
|
6604
|
+
throw new Error('Invalid arguments');
|
|
6605
|
+
}
|
|
6606
|
+
|
|
6607
|
+
const wireTransaction = transaction.serialize();
|
|
6608
|
+
return await this.sendRawTransaction(wireTransaction, options);
|
|
6609
|
+
}
|
|
6610
|
+
|
|
6611
|
+
if (signersOrOptions === undefined || !Array.isArray(signersOrOptions)) {
|
|
6612
|
+
throw new Error('Invalid arguments');
|
|
6613
|
+
}
|
|
6614
|
+
|
|
6615
|
+
const signers = signersOrOptions;
|
|
6616
|
+
|
|
6126
6617
|
if (transaction.nonceInfo) {
|
|
6127
6618
|
transaction.sign(...signers);
|
|
6128
6619
|
} else {
|
|
@@ -7649,7 +8140,7 @@ class Secp256k1Program {
|
|
|
7649
8140
|
assert(publicKey.length === PUBLIC_KEY_BYTES, `Public key must be ${PUBLIC_KEY_BYTES} bytes but received ${publicKey.length} bytes`);
|
|
7650
8141
|
|
|
7651
8142
|
try {
|
|
7652
|
-
return buffer.Buffer.from(
|
|
8143
|
+
return buffer.Buffer.from(sha3.keccak_256(toBuffer(publicKey))).slice(-ETHEREUM_ADDRESS_BYTES);
|
|
7653
8144
|
} catch (error) {
|
|
7654
8145
|
throw new Error(`Error constructing Ethereum address: ${error}`);
|
|
7655
8146
|
}
|
|
@@ -7749,7 +8240,7 @@ class Secp256k1Program {
|
|
|
7749
8240
|
/* isCompressed */
|
|
7750
8241
|
).slice(1); // throw away leading byte
|
|
7751
8242
|
|
|
7752
|
-
const messageHash = buffer.Buffer.from(
|
|
8243
|
+
const messageHash = buffer.Buffer.from(sha3.keccak_256(toBuffer(message)));
|
|
7753
8244
|
const [signature, recoveryId] = ecdsaSign(messageHash, privateKey);
|
|
7754
8245
|
return this.createInstructionWithPublicKey({
|
|
7755
8246
|
publicKey,
|
|
@@ -8643,6 +9134,33 @@ class VoteInstruction {
|
|
|
8643
9134
|
}
|
|
8644
9135
|
};
|
|
8645
9136
|
}
|
|
9137
|
+
/**
|
|
9138
|
+
* Decode an authorize instruction and retrieve the instruction params.
|
|
9139
|
+
*/
|
|
9140
|
+
|
|
9141
|
+
|
|
9142
|
+
static decodeAuthorizeWithSeed(instruction) {
|
|
9143
|
+
this.checkProgramId(instruction.programId);
|
|
9144
|
+
this.checkKeyLength(instruction.keys, 3);
|
|
9145
|
+
const {
|
|
9146
|
+
voteAuthorizeWithSeedArgs: {
|
|
9147
|
+
currentAuthorityDerivedKeyOwnerPubkey,
|
|
9148
|
+
currentAuthorityDerivedKeySeed,
|
|
9149
|
+
newAuthorized,
|
|
9150
|
+
voteAuthorizationType
|
|
9151
|
+
}
|
|
9152
|
+
} = decodeData$1(VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed, instruction.data);
|
|
9153
|
+
return {
|
|
9154
|
+
currentAuthorityDerivedKeyBasePubkey: instruction.keys[2].pubkey,
|
|
9155
|
+
currentAuthorityDerivedKeyOwnerPubkey: new PublicKey(currentAuthorityDerivedKeyOwnerPubkey),
|
|
9156
|
+
currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
|
|
9157
|
+
newAuthorizedPubkey: new PublicKey(newAuthorized),
|
|
9158
|
+
voteAuthorizationType: {
|
|
9159
|
+
index: voteAuthorizationType
|
|
9160
|
+
},
|
|
9161
|
+
votePubkey: instruction.keys[0].pubkey
|
|
9162
|
+
};
|
|
9163
|
+
}
|
|
8646
9164
|
/**
|
|
8647
9165
|
* Decode a withdraw instruction and retrieve the instruction params.
|
|
8648
9166
|
*/
|
|
@@ -8699,6 +9217,10 @@ const VOTE_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
|
8699
9217
|
Withdraw: {
|
|
8700
9218
|
index: 3,
|
|
8701
9219
|
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), BufferLayout__namespace.ns64('lamports')])
|
|
9220
|
+
},
|
|
9221
|
+
AuthorizeWithSeed: {
|
|
9222
|
+
index: 10,
|
|
9223
|
+
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), voteAuthorizeWithSeedArgs()])
|
|
8702
9224
|
}
|
|
8703
9225
|
});
|
|
8704
9226
|
/**
|
|
@@ -8827,6 +9349,49 @@ class VoteProgram {
|
|
|
8827
9349
|
data
|
|
8828
9350
|
});
|
|
8829
9351
|
}
|
|
9352
|
+
/**
|
|
9353
|
+
* Generate a transaction that authorizes a new Voter or Withdrawer on the Vote account
|
|
9354
|
+
* where the current Voter or Withdrawer authority is a derived key.
|
|
9355
|
+
*/
|
|
9356
|
+
|
|
9357
|
+
|
|
9358
|
+
static authorizeWithSeed(params) {
|
|
9359
|
+
const {
|
|
9360
|
+
currentAuthorityDerivedKeyBasePubkey,
|
|
9361
|
+
currentAuthorityDerivedKeyOwnerPubkey,
|
|
9362
|
+
currentAuthorityDerivedKeySeed,
|
|
9363
|
+
newAuthorizedPubkey,
|
|
9364
|
+
voteAuthorizationType,
|
|
9365
|
+
votePubkey
|
|
9366
|
+
} = params;
|
|
9367
|
+
const type = VOTE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed;
|
|
9368
|
+
const data = encodeData(type, {
|
|
9369
|
+
voteAuthorizeWithSeedArgs: {
|
|
9370
|
+
currentAuthorityDerivedKeyOwnerPubkey: toBuffer(currentAuthorityDerivedKeyOwnerPubkey.toBuffer()),
|
|
9371
|
+
currentAuthorityDerivedKeySeed: currentAuthorityDerivedKeySeed,
|
|
9372
|
+
newAuthorized: toBuffer(newAuthorizedPubkey.toBuffer()),
|
|
9373
|
+
voteAuthorizationType: voteAuthorizationType.index
|
|
9374
|
+
}
|
|
9375
|
+
});
|
|
9376
|
+
const keys = [{
|
|
9377
|
+
pubkey: votePubkey,
|
|
9378
|
+
isSigner: false,
|
|
9379
|
+
isWritable: true
|
|
9380
|
+
}, {
|
|
9381
|
+
pubkey: SYSVAR_CLOCK_PUBKEY,
|
|
9382
|
+
isSigner: false,
|
|
9383
|
+
isWritable: false
|
|
9384
|
+
}, {
|
|
9385
|
+
pubkey: currentAuthorityDerivedKeyBasePubkey,
|
|
9386
|
+
isSigner: true,
|
|
9387
|
+
isWritable: false
|
|
9388
|
+
}];
|
|
9389
|
+
return new Transaction().add({
|
|
9390
|
+
keys,
|
|
9391
|
+
programId: this.programId,
|
|
9392
|
+
data
|
|
9393
|
+
});
|
|
9394
|
+
}
|
|
8830
9395
|
/**
|
|
8831
9396
|
* Generate a transaction to withdraw from a Vote account.
|
|
8832
9397
|
*/
|
|
@@ -9173,6 +9738,7 @@ exports.Loader = Loader;
|
|
|
9173
9738
|
exports.Lockup = Lockup;
|
|
9174
9739
|
exports.MAX_SEED_LENGTH = MAX_SEED_LENGTH;
|
|
9175
9740
|
exports.Message = Message;
|
|
9741
|
+
exports.MessageAccountKeys = MessageAccountKeys;
|
|
9176
9742
|
exports.MessageV0 = MessageV0;
|
|
9177
9743
|
exports.NONCE_ACCOUNT_LENGTH = NONCE_ACCOUNT_LENGTH;
|
|
9178
9744
|
exports.NonceAccount = NonceAccount;
|
|
@@ -9207,6 +9773,7 @@ exports.Transaction = Transaction;
|
|
|
9207
9773
|
exports.TransactionExpiredBlockheightExceededError = TransactionExpiredBlockheightExceededError;
|
|
9208
9774
|
exports.TransactionExpiredTimeoutError = TransactionExpiredTimeoutError;
|
|
9209
9775
|
exports.TransactionInstruction = TransactionInstruction;
|
|
9776
|
+
exports.TransactionMessage = TransactionMessage;
|
|
9210
9777
|
exports.VALIDATOR_INFO_KEY = VALIDATOR_INFO_KEY;
|
|
9211
9778
|
exports.VERSION_PREFIX_MASK = VERSION_PREFIX_MASK;
|
|
9212
9779
|
exports.VOTE_PROGRAM_ID = VOTE_PROGRAM_ID;
|