@solana/transactions 2.0.0-experimental.e8095b1 → 2.0.0-experimental.e9e224b
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/README.md +314 -5
- package/dist/index.browser.cjs +354 -138
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +357 -140
- package/dist/index.browser.js.map +1 -1
- package/dist/index.development.js +767 -1031
- package/dist/index.development.js.map +1 -1
- package/dist/index.native.js +355 -140
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +354 -136
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +357 -140
- package/dist/index.node.js.map +1 -1
- package/dist/index.production.min.js +20 -17
- package/dist/types/decompile-transaction.d.ts +7 -0
- package/dist/types/durable-nonce.d.ts +2 -3
- package/dist/types/serializers/message.d.ts +4 -4
- package/dist/types/serializers/transaction.d.ts +7 -4
- package/dist/types/signatures.d.ts +1 -0
- package/dist/types/wire-transaction.d.ts +1 -1
- package/package.json +12 -11
- package/dist/types/accounts.d.ts.map +0 -1
- package/dist/types/blockhash.d.ts.map +0 -1
- package/dist/types/compile-address-table-lookups.d.ts.map +0 -1
- package/dist/types/compile-header.d.ts.map +0 -1
- package/dist/types/compile-instructions.d.ts.map +0 -1
- package/dist/types/compile-lifetime-token.d.ts.map +0 -1
- package/dist/types/compile-static-accounts.d.ts.map +0 -1
- package/dist/types/compile-transaction.d.ts.map +0 -1
- package/dist/types/create-transaction.d.ts.map +0 -1
- package/dist/types/durable-nonce.d.ts.map +0 -1
- package/dist/types/fee-payer.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/instructions.d.ts.map +0 -1
- package/dist/types/message.d.ts.map +0 -1
- package/dist/types/serializers/address-table-lookup.d.ts.map +0 -1
- package/dist/types/serializers/header.d.ts.map +0 -1
- package/dist/types/serializers/index.d.ts.map +0 -1
- package/dist/types/serializers/instruction.d.ts.map +0 -1
- package/dist/types/serializers/message.d.ts.map +0 -1
- package/dist/types/serializers/transaction-version.d.ts.map +0 -1
- package/dist/types/serializers/transaction.d.ts.map +0 -1
- package/dist/types/serializers/unimplemented.d.ts +0 -3
- package/dist/types/serializers/unimplemented.d.ts.map +0 -1
- package/dist/types/signatures.d.ts.map +0 -1
- package/dist/types/types.d.ts.map +0 -1
- package/dist/types/unsigned-transaction.d.ts.map +0 -1
- package/dist/types/wire-transaction.d.ts.map +0 -1
package/dist/index.browser.cjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var addresses = require('@solana/addresses');
|
|
3
|
+
var codecsStrings = require('@solana/codecs-strings');
|
|
5
4
|
var codecsCore = require('@solana/codecs-core');
|
|
6
5
|
var codecsDataStructures = require('@solana/codecs-data-structures');
|
|
7
6
|
var codecsNumbers = require('@solana/codecs-numbers');
|
|
7
|
+
var addresses = require('@solana/addresses');
|
|
8
|
+
var functional = require('@solana/functional');
|
|
8
9
|
var keys = require('@solana/keys');
|
|
9
10
|
|
|
10
11
|
// ../build-scripts/env-shim.ts
|
|
@@ -25,7 +26,10 @@ function getUnsignedTransaction(transaction) {
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
// src/blockhash.ts
|
|
29
|
+
var base58Encoder;
|
|
28
30
|
function assertIsBlockhash(putativeBlockhash) {
|
|
31
|
+
if (!base58Encoder)
|
|
32
|
+
base58Encoder = codecsStrings.getBase58Encoder();
|
|
29
33
|
try {
|
|
30
34
|
if (
|
|
31
35
|
// Lowest value (32 bytes of zeroes)
|
|
@@ -34,8 +38,8 @@ function assertIsBlockhash(putativeBlockhash) {
|
|
|
34
38
|
) {
|
|
35
39
|
throw new Error("Expected input string to decode to a byte array of length 32.");
|
|
36
40
|
}
|
|
37
|
-
const
|
|
38
|
-
const numBytes =
|
|
41
|
+
const bytes = base58Encoder.encode(putativeBlockhash);
|
|
42
|
+
const numBytes = bytes.byteLength;
|
|
39
43
|
if (numBytes !== 32) {
|
|
40
44
|
throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
|
|
41
45
|
}
|
|
@@ -120,7 +124,7 @@ function isAdvanceNonceAccountInstruction(instruction) {
|
|
|
120
124
|
instruction.accounts?.length === 3 && // First account is nonce account address
|
|
121
125
|
instruction.accounts[0].address != null && instruction.accounts[0].role === AccountRole.WRITABLE && // Second account is recent blockhashes sysvar
|
|
122
126
|
instruction.accounts[1].address === RECENT_BLOCKHASHES_SYSVAR_ADDRESS && instruction.accounts[1].role === AccountRole.READONLY && // Third account is nonce authority account
|
|
123
|
-
instruction.accounts[2].address != null && instruction.accounts[2].role
|
|
127
|
+
instruction.accounts[2].address != null && isSignerRole(instruction.accounts[2].role);
|
|
124
128
|
}
|
|
125
129
|
function isAdvanceNonceAccountInstructionData(data) {
|
|
126
130
|
return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;
|
|
@@ -128,21 +132,38 @@ function isAdvanceNonceAccountInstructionData(data) {
|
|
|
128
132
|
function isDurableNonceTransaction(transaction) {
|
|
129
133
|
return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
|
|
130
134
|
}
|
|
135
|
+
function isAdvanceNonceAccountInstructionForNonce(instruction, nonceAccountAddress, nonceAuthorityAddress) {
|
|
136
|
+
return instruction.accounts[0].address === nonceAccountAddress && instruction.accounts[2].address === nonceAuthorityAddress;
|
|
137
|
+
}
|
|
131
138
|
function setTransactionLifetimeUsingDurableNonce({
|
|
132
139
|
nonce,
|
|
133
140
|
nonceAccountAddress,
|
|
134
141
|
nonceAuthorityAddress
|
|
135
142
|
}, transaction) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
143
|
+
let newInstructions;
|
|
144
|
+
const firstInstruction = transaction.instructions[0];
|
|
145
|
+
if (firstInstruction && isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
146
|
+
if (isAdvanceNonceAccountInstructionForNonce(firstInstruction, nonceAccountAddress, nonceAuthorityAddress)) {
|
|
147
|
+
if (isDurableNonceTransaction(transaction) && transaction.lifetimeConstraint.nonce === nonce) {
|
|
148
|
+
return transaction;
|
|
149
|
+
} else {
|
|
150
|
+
newInstructions = [firstInstruction, ...transaction.instructions.slice(1)];
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
newInstructions = [
|
|
154
|
+
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
155
|
+
...transaction.instructions.slice(1)
|
|
156
|
+
];
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
newInstructions = [
|
|
160
|
+
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
161
|
+
...transaction.instructions
|
|
162
|
+
];
|
|
139
163
|
}
|
|
140
164
|
const out = {
|
|
141
165
|
...getUnsignedTransaction(transaction),
|
|
142
|
-
instructions:
|
|
143
|
-
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
144
|
-
...isAlreadyDurableNonceTransaction ? transaction.instructions.slice(1) : transaction.instructions
|
|
145
|
-
],
|
|
166
|
+
instructions: newInstructions,
|
|
146
167
|
lifetimeConstraint: {
|
|
147
168
|
nonce
|
|
148
169
|
}
|
|
@@ -465,6 +486,116 @@ function getCompiledTransaction(transaction) {
|
|
|
465
486
|
signatures
|
|
466
487
|
};
|
|
467
488
|
}
|
|
489
|
+
function getAccountMetas(message) {
|
|
490
|
+
const { header } = message;
|
|
491
|
+
const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
|
|
492
|
+
const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
|
|
493
|
+
const accountMetas = [];
|
|
494
|
+
let accountIndex = 0;
|
|
495
|
+
for (let i = 0; i < numWritableSignerAccounts; i++) {
|
|
496
|
+
accountMetas.push({
|
|
497
|
+
address: message.staticAccounts[accountIndex],
|
|
498
|
+
role: AccountRole.WRITABLE_SIGNER
|
|
499
|
+
});
|
|
500
|
+
accountIndex++;
|
|
501
|
+
}
|
|
502
|
+
for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
|
|
503
|
+
accountMetas.push({
|
|
504
|
+
address: message.staticAccounts[accountIndex],
|
|
505
|
+
role: AccountRole.READONLY_SIGNER
|
|
506
|
+
});
|
|
507
|
+
accountIndex++;
|
|
508
|
+
}
|
|
509
|
+
for (let i = 0; i < numWritableNonSignerAccounts; i++) {
|
|
510
|
+
accountMetas.push({
|
|
511
|
+
address: message.staticAccounts[accountIndex],
|
|
512
|
+
role: AccountRole.WRITABLE
|
|
513
|
+
});
|
|
514
|
+
accountIndex++;
|
|
515
|
+
}
|
|
516
|
+
for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
|
|
517
|
+
accountMetas.push({
|
|
518
|
+
address: message.staticAccounts[accountIndex],
|
|
519
|
+
role: AccountRole.READONLY
|
|
520
|
+
});
|
|
521
|
+
accountIndex++;
|
|
522
|
+
}
|
|
523
|
+
return accountMetas;
|
|
524
|
+
}
|
|
525
|
+
function convertInstruction(instruction, accountMetas) {
|
|
526
|
+
const programAddress = accountMetas[instruction.programAddressIndex]?.address;
|
|
527
|
+
if (!programAddress) {
|
|
528
|
+
throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
|
|
529
|
+
}
|
|
530
|
+
const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
|
|
531
|
+
const { data } = instruction;
|
|
532
|
+
return {
|
|
533
|
+
programAddress,
|
|
534
|
+
...accounts && accounts.length ? { accounts } : {},
|
|
535
|
+
...data && data.length ? { data } : {}
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
|
|
539
|
+
if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
540
|
+
return {
|
|
541
|
+
blockhash: messageLifetimeToken,
|
|
542
|
+
lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
|
|
543
|
+
// U64 MAX
|
|
544
|
+
};
|
|
545
|
+
} else {
|
|
546
|
+
const nonceAccountAddress = firstInstruction.accounts[0].address;
|
|
547
|
+
addresses.assertIsAddress(nonceAccountAddress);
|
|
548
|
+
const nonceAuthorityAddress = firstInstruction.accounts[2].address;
|
|
549
|
+
addresses.assertIsAddress(nonceAuthorityAddress);
|
|
550
|
+
return {
|
|
551
|
+
nonce: messageLifetimeToken,
|
|
552
|
+
nonceAccountAddress,
|
|
553
|
+
nonceAuthorityAddress
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
function convertSignatures(compiledTransaction) {
|
|
558
|
+
const {
|
|
559
|
+
compiledMessage: { staticAccounts },
|
|
560
|
+
signatures
|
|
561
|
+
} = compiledTransaction;
|
|
562
|
+
return signatures.reduce((acc, sig, index) => {
|
|
563
|
+
const allZeros = sig.every((byte) => byte === 0);
|
|
564
|
+
if (allZeros)
|
|
565
|
+
return acc;
|
|
566
|
+
const address = staticAccounts[index];
|
|
567
|
+
return { ...acc, [address]: sig };
|
|
568
|
+
}, {});
|
|
569
|
+
}
|
|
570
|
+
function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
|
|
571
|
+
const { compiledMessage } = compiledTransaction;
|
|
572
|
+
if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
|
|
573
|
+
throw new Error("Cannot convert transaction with addressTableLookups");
|
|
574
|
+
}
|
|
575
|
+
const feePayer = compiledMessage.staticAccounts[0];
|
|
576
|
+
if (!feePayer)
|
|
577
|
+
throw new Error("No fee payer set in CompiledTransaction");
|
|
578
|
+
const accountMetas = getAccountMetas(compiledMessage);
|
|
579
|
+
const instructions = compiledMessage.instructions.map(
|
|
580
|
+
(compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
|
|
581
|
+
);
|
|
582
|
+
const firstInstruction = instructions[0];
|
|
583
|
+
const lifetimeConstraint = getLifetimeConstraint(
|
|
584
|
+
compiledMessage.lifetimeToken,
|
|
585
|
+
firstInstruction,
|
|
586
|
+
lastValidBlockHeight
|
|
587
|
+
);
|
|
588
|
+
const signatures = convertSignatures(compiledTransaction);
|
|
589
|
+
return functional.pipe(
|
|
590
|
+
createTransaction({ version: compiledMessage.version }),
|
|
591
|
+
(tx) => setTransactionFeePayer(feePayer, tx),
|
|
592
|
+
(tx) => instructions.reduce((acc, instruction) => {
|
|
593
|
+
return appendTransactionInstruction(instruction, acc);
|
|
594
|
+
}, tx),
|
|
595
|
+
(tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
|
|
596
|
+
(tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
|
|
597
|
+
);
|
|
598
|
+
}
|
|
468
599
|
var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
|
|
469
600
|
var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
|
|
470
601
|
var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
|
|
@@ -521,32 +652,54 @@ function getAddressTableLookupDecoder() {
|
|
|
521
652
|
}
|
|
522
653
|
return memoizedAddressTableLookupDecoder;
|
|
523
654
|
}
|
|
524
|
-
|
|
525
|
-
|
|
655
|
+
var memoizedU8Encoder;
|
|
656
|
+
function getMemoizedU8Encoder() {
|
|
657
|
+
if (!memoizedU8Encoder)
|
|
658
|
+
memoizedU8Encoder = codecsNumbers.getU8Encoder();
|
|
659
|
+
return memoizedU8Encoder;
|
|
526
660
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
661
|
+
function getMemoizedU8EncoderDescription(description) {
|
|
662
|
+
const encoder = getMemoizedU8Encoder();
|
|
663
|
+
return {
|
|
664
|
+
...encoder,
|
|
665
|
+
description: description ?? encoder.description
|
|
666
|
+
};
|
|
532
667
|
}
|
|
533
|
-
|
|
534
|
-
|
|
668
|
+
var memoizedU8Decoder;
|
|
669
|
+
function getMemoizedU8Decoder() {
|
|
670
|
+
if (!memoizedU8Decoder)
|
|
671
|
+
memoizedU8Decoder = codecsNumbers.getU8Decoder();
|
|
672
|
+
return memoizedU8Decoder;
|
|
673
|
+
}
|
|
674
|
+
function getMemoizedU8DecoderDescription(description) {
|
|
675
|
+
const decoder = getMemoizedU8Decoder();
|
|
535
676
|
return {
|
|
536
|
-
...
|
|
537
|
-
description: description ??
|
|
677
|
+
...decoder,
|
|
678
|
+
description: description ?? decoder.description
|
|
538
679
|
};
|
|
539
680
|
}
|
|
540
681
|
var numSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are required to sign this transaction" : void 0;
|
|
541
682
|
var numReadonlySignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are required to sign this transaction, but may not be writable" : void 0;
|
|
542
683
|
var numReadonlyNonSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable" : void 0;
|
|
543
684
|
var messageHeaderDescription = __DEV__ ? "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses" : void 0;
|
|
544
|
-
function
|
|
545
|
-
return codecsDataStructures.
|
|
685
|
+
function getMessageHeaderEncoder() {
|
|
686
|
+
return codecsDataStructures.getStructEncoder(
|
|
546
687
|
[
|
|
547
|
-
["numSignerAccounts",
|
|
548
|
-
["numReadonlySignerAccounts",
|
|
549
|
-
["numReadonlyNonSignerAccounts",
|
|
688
|
+
["numSignerAccounts", getMemoizedU8EncoderDescription(numSignerAccountsDescription)],
|
|
689
|
+
["numReadonlySignerAccounts", getMemoizedU8EncoderDescription(numReadonlySignerAccountsDescription)],
|
|
690
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8EncoderDescription(numReadonlyNonSignerAccountsDescription)]
|
|
691
|
+
],
|
|
692
|
+
{
|
|
693
|
+
description: messageHeaderDescription
|
|
694
|
+
}
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
function getMessageHeaderDecoder() {
|
|
698
|
+
return codecsDataStructures.getStructDecoder(
|
|
699
|
+
[
|
|
700
|
+
["numSignerAccounts", getMemoizedU8DecoderDescription(numSignerAccountsDescription)],
|
|
701
|
+
["numReadonlySignerAccounts", getMemoizedU8DecoderDescription(numReadonlySignerAccountsDescription)],
|
|
702
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8DecoderDescription(numReadonlyNonSignerAccountsDescription)]
|
|
550
703
|
],
|
|
551
704
|
{
|
|
552
705
|
description: messageHeaderDescription
|
|
@@ -618,17 +771,14 @@ function getInstructionDecoder() {
|
|
|
618
771
|
}
|
|
619
772
|
return memoizedGetInstructionDecoder;
|
|
620
773
|
}
|
|
621
|
-
function getInstructionCodec() {
|
|
622
|
-
return codecsCore.combineCodec(getInstructionEncoder(), getInstructionDecoder());
|
|
623
|
-
}
|
|
624
774
|
var VERSION_FLAG_MASK = 128;
|
|
625
775
|
var BASE_CONFIG = {
|
|
626
776
|
description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
|
|
627
777
|
fixedSize: null,
|
|
628
778
|
maxSize: 1
|
|
629
779
|
};
|
|
630
|
-
function decode(
|
|
631
|
-
const firstByte =
|
|
780
|
+
function decode(bytes, offset = 0) {
|
|
781
|
+
const firstByte = bytes[offset];
|
|
632
782
|
if ((firstByte & VERSION_FLAG_MASK) === 0) {
|
|
633
783
|
return ["legacy", offset];
|
|
634
784
|
} else {
|
|
@@ -657,128 +807,187 @@ function getTransactionVersionEncoder() {
|
|
|
657
807
|
encode
|
|
658
808
|
};
|
|
659
809
|
}
|
|
660
|
-
function getTransactionVersionCodec() {
|
|
661
|
-
return codecsCore.combineCodec(getTransactionVersionEncoder(), getTransactionVersionDecoder());
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
// src/serializers/unimplemented.ts
|
|
665
|
-
function getError(type, name) {
|
|
666
|
-
const functionSuffix = name + type[0].toUpperCase() + type.slice(1);
|
|
667
|
-
return new Error(
|
|
668
|
-
`No ${type} exists for ${name}. Use \`get${functionSuffix}()\` if you need a ${type}, and \`get${name}Codec()\` if you need to both encode and decode ${name}`
|
|
669
|
-
);
|
|
670
|
-
}
|
|
671
|
-
function getUnimplementedDecoder(name) {
|
|
672
|
-
return () => {
|
|
673
|
-
throw getError("decoder", name);
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
810
|
|
|
677
811
|
// src/serializers/message.ts
|
|
678
|
-
var
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
if (compiledMessage.version === "legacy") {
|
|
685
|
-
return umiSerializers.struct(getPreludeStructSerializerTuple()).serialize(compiledMessage);
|
|
686
|
-
} else {
|
|
687
|
-
return umiSerializers.mapSerializer(
|
|
688
|
-
umiSerializers.struct([
|
|
689
|
-
...getPreludeStructSerializerTuple(),
|
|
690
|
-
["addressTableLookups", getAddressTableLookupsSerializer()]
|
|
691
|
-
]),
|
|
692
|
-
(value) => {
|
|
693
|
-
if (value.version === "legacy") {
|
|
694
|
-
return value;
|
|
695
|
-
}
|
|
696
|
-
return {
|
|
697
|
-
...value,
|
|
698
|
-
addressTableLookups: value.addressTableLookups ?? []
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
).serialize(compiledMessage);
|
|
702
|
-
}
|
|
812
|
+
var staticAccountsDescription = __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "staticAccounts";
|
|
813
|
+
var lifetimeTokenDescription = __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "lifetimeToken";
|
|
814
|
+
var instructionsDescription = __DEV__ ? "A compact-array of instructions belonging to this transaction" : "instructions";
|
|
815
|
+
var addressTableLookupsDescription = __DEV__ ? "A compact array of address table lookups belonging to this transaction" : "addressTableLookups";
|
|
816
|
+
function getCompiledMessageLegacyEncoder() {
|
|
817
|
+
return codecsDataStructures.getStructEncoder(getPreludeStructEncoderTuple());
|
|
703
818
|
}
|
|
704
|
-
function
|
|
705
|
-
return
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
819
|
+
function getCompiledMessageVersionedEncoder() {
|
|
820
|
+
return codecsCore.mapEncoder(
|
|
821
|
+
codecsDataStructures.getStructEncoder([
|
|
822
|
+
...getPreludeStructEncoderTuple(),
|
|
823
|
+
["addressTableLookups", getAddressTableLookupArrayEncoder()]
|
|
824
|
+
]),
|
|
825
|
+
(value) => {
|
|
826
|
+
if (value.version === "legacy") {
|
|
827
|
+
return value;
|
|
828
|
+
}
|
|
829
|
+
return {
|
|
830
|
+
...value,
|
|
831
|
+
addressTableLookups: value.addressTableLookups ?? []
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
);
|
|
712
835
|
}
|
|
713
|
-
function
|
|
836
|
+
function getPreludeStructEncoderTuple() {
|
|
714
837
|
return [
|
|
715
|
-
["version",
|
|
716
|
-
["header",
|
|
838
|
+
["version", getTransactionVersionEncoder()],
|
|
839
|
+
["header", getMessageHeaderEncoder()],
|
|
717
840
|
[
|
|
718
841
|
"staticAccounts",
|
|
719
|
-
|
|
720
|
-
description:
|
|
721
|
-
size:
|
|
842
|
+
codecsDataStructures.getArrayEncoder(addresses.getAddressEncoder(), {
|
|
843
|
+
description: staticAccountsDescription,
|
|
844
|
+
size: codecsNumbers.getShortU16Encoder()
|
|
722
845
|
})
|
|
723
846
|
],
|
|
724
847
|
[
|
|
725
848
|
"lifetimeToken",
|
|
726
|
-
|
|
727
|
-
description:
|
|
728
|
-
encoding:
|
|
849
|
+
codecsStrings.getStringEncoder({
|
|
850
|
+
description: lifetimeTokenDescription,
|
|
851
|
+
encoding: codecsStrings.getBase58Encoder(),
|
|
729
852
|
size: 32
|
|
730
853
|
})
|
|
731
854
|
],
|
|
732
855
|
[
|
|
733
856
|
"instructions",
|
|
734
|
-
|
|
735
|
-
description:
|
|
736
|
-
size:
|
|
857
|
+
codecsDataStructures.getArrayEncoder(getInstructionEncoder(), {
|
|
858
|
+
description: instructionsDescription,
|
|
859
|
+
size: codecsNumbers.getShortU16Encoder()
|
|
737
860
|
})
|
|
738
861
|
]
|
|
739
862
|
];
|
|
740
863
|
}
|
|
741
|
-
function
|
|
742
|
-
return
|
|
743
|
-
|
|
744
|
-
|
|
864
|
+
function getPreludeStructDecoderTuple() {
|
|
865
|
+
return [
|
|
866
|
+
["version", getTransactionVersionDecoder()],
|
|
867
|
+
["header", getMessageHeaderDecoder()],
|
|
868
|
+
[
|
|
869
|
+
"staticAccounts",
|
|
870
|
+
codecsDataStructures.getArrayDecoder(addresses.getAddressDecoder(), {
|
|
871
|
+
description: staticAccountsDescription,
|
|
872
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
873
|
+
})
|
|
874
|
+
],
|
|
875
|
+
[
|
|
876
|
+
"lifetimeToken",
|
|
877
|
+
codecsStrings.getStringDecoder({
|
|
878
|
+
description: lifetimeTokenDescription,
|
|
879
|
+
encoding: codecsStrings.getBase58Decoder(),
|
|
880
|
+
size: 32
|
|
881
|
+
})
|
|
882
|
+
],
|
|
883
|
+
[
|
|
884
|
+
"instructions",
|
|
885
|
+
codecsDataStructures.getArrayDecoder(getInstructionDecoder(), {
|
|
886
|
+
description: instructionsDescription,
|
|
887
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
888
|
+
})
|
|
889
|
+
],
|
|
890
|
+
["addressTableLookups", getAddressTableLookupArrayDecoder()]
|
|
891
|
+
];
|
|
892
|
+
}
|
|
893
|
+
function getAddressTableLookupArrayEncoder() {
|
|
894
|
+
return codecsDataStructures.getArrayEncoder(getAddressTableLookupEncoder(), {
|
|
895
|
+
description: addressTableLookupsDescription,
|
|
896
|
+
size: codecsNumbers.getShortU16Encoder()
|
|
745
897
|
});
|
|
746
898
|
}
|
|
899
|
+
function getAddressTableLookupArrayDecoder() {
|
|
900
|
+
return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), {
|
|
901
|
+
description: addressTableLookupsDescription,
|
|
902
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
var messageDescription = __DEV__ ? "The wire format of a Solana transaction message" : "message";
|
|
747
906
|
function getCompiledMessageEncoder() {
|
|
748
907
|
return {
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
908
|
+
description: messageDescription,
|
|
909
|
+
encode: (compiledMessage) => {
|
|
910
|
+
if (compiledMessage.version === "legacy") {
|
|
911
|
+
return getCompiledMessageLegacyEncoder().encode(compiledMessage);
|
|
912
|
+
} else {
|
|
913
|
+
return getCompiledMessageVersionedEncoder().encode(compiledMessage);
|
|
914
|
+
}
|
|
915
|
+
},
|
|
916
|
+
fixedSize: null,
|
|
917
|
+
maxSize: null
|
|
752
918
|
};
|
|
753
919
|
}
|
|
920
|
+
function getCompiledMessageDecoder() {
|
|
921
|
+
return codecsCore.mapDecoder(
|
|
922
|
+
codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple(), {
|
|
923
|
+
description: messageDescription
|
|
924
|
+
}),
|
|
925
|
+
({ addressTableLookups, ...restOfMessage }) => {
|
|
926
|
+
if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
|
|
927
|
+
return restOfMessage;
|
|
928
|
+
}
|
|
929
|
+
return { ...restOfMessage, addressTableLookups };
|
|
930
|
+
}
|
|
931
|
+
);
|
|
932
|
+
}
|
|
754
933
|
|
|
755
934
|
// src/serializers/transaction.ts
|
|
756
|
-
var
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
};
|
|
761
|
-
function serialize2(transaction) {
|
|
762
|
-
const compiledTransaction = getCompiledTransaction(transaction);
|
|
763
|
-
return umiSerializers.struct([
|
|
935
|
+
var signaturesDescription = __DEV__ ? "A compact array of 64-byte, base-64 encoded Ed25519 signatures" : "signatures";
|
|
936
|
+
var transactionDescription = __DEV__ ? "The wire format of a Solana transaction" : "transaction";
|
|
937
|
+
function getCompiledTransactionEncoder() {
|
|
938
|
+
return codecsDataStructures.getStructEncoder(
|
|
764
939
|
[
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
940
|
+
[
|
|
941
|
+
"signatures",
|
|
942
|
+
codecsDataStructures.getArrayEncoder(codecsDataStructures.getBytesEncoder({ size: 64 }), {
|
|
943
|
+
description: signaturesDescription,
|
|
944
|
+
size: codecsNumbers.getShortU16Encoder()
|
|
945
|
+
})
|
|
946
|
+
],
|
|
947
|
+
["compiledMessage", getCompiledMessageEncoder()]
|
|
770
948
|
],
|
|
771
|
-
|
|
772
|
-
|
|
949
|
+
{
|
|
950
|
+
description: transactionDescription
|
|
951
|
+
}
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
function getSignatureDecoder() {
|
|
955
|
+
return codecsCore.mapDecoder(codecsDataStructures.getBytesDecoder({ size: 64 }), (bytes) => bytes);
|
|
956
|
+
}
|
|
957
|
+
function getCompiledTransactionDecoder() {
|
|
958
|
+
return codecsDataStructures.getStructDecoder(
|
|
959
|
+
[
|
|
960
|
+
[
|
|
961
|
+
"signatures",
|
|
962
|
+
codecsDataStructures.getArrayDecoder(getSignatureDecoder(), {
|
|
963
|
+
description: signaturesDescription,
|
|
964
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
965
|
+
})
|
|
966
|
+
],
|
|
967
|
+
["compiledMessage", getCompiledMessageDecoder()]
|
|
968
|
+
],
|
|
969
|
+
{
|
|
970
|
+
description: transactionDescription
|
|
971
|
+
}
|
|
972
|
+
);
|
|
773
973
|
}
|
|
774
974
|
function getTransactionEncoder() {
|
|
775
|
-
return
|
|
776
|
-
...BASE_CONFIG3,
|
|
777
|
-
deserialize: getUnimplementedDecoder("CompiledMessage"),
|
|
778
|
-
serialize: serialize2
|
|
779
|
-
};
|
|
975
|
+
return codecsCore.mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
|
|
780
976
|
}
|
|
977
|
+
function getTransactionDecoder(lastValidBlockHeight) {
|
|
978
|
+
return codecsCore.mapDecoder(
|
|
979
|
+
getCompiledTransactionDecoder(),
|
|
980
|
+
(compiledTransaction) => decompileTransaction(compiledTransaction, lastValidBlockHeight)
|
|
981
|
+
);
|
|
982
|
+
}
|
|
983
|
+
function getTransactionCodec(lastValidBlockHeight) {
|
|
984
|
+
return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
|
|
985
|
+
}
|
|
986
|
+
var base58Encoder2;
|
|
987
|
+
var base58Decoder;
|
|
781
988
|
function assertIsTransactionSignature(putativeTransactionSignature) {
|
|
989
|
+
if (!base58Encoder2)
|
|
990
|
+
base58Encoder2 = codecsStrings.getBase58Encoder();
|
|
782
991
|
try {
|
|
783
992
|
if (
|
|
784
993
|
// Lowest value (64 bytes of zeroes)
|
|
@@ -787,8 +996,8 @@ function assertIsTransactionSignature(putativeTransactionSignature) {
|
|
|
787
996
|
) {
|
|
788
997
|
throw new Error("Expected input string to decode to a byte array of length 64.");
|
|
789
998
|
}
|
|
790
|
-
const
|
|
791
|
-
const numBytes =
|
|
999
|
+
const bytes = base58Encoder2.encode(putativeTransactionSignature);
|
|
1000
|
+
const numBytes = bytes.byteLength;
|
|
792
1001
|
if (numBytes !== 64) {
|
|
793
1002
|
throw new Error(`Expected input string to decode to a byte array of length 64. Actual length: ${numBytes}`);
|
|
794
1003
|
}
|
|
@@ -799,6 +1008,8 @@ function assertIsTransactionSignature(putativeTransactionSignature) {
|
|
|
799
1008
|
}
|
|
800
1009
|
}
|
|
801
1010
|
function isTransactionSignature(putativeTransactionSignature) {
|
|
1011
|
+
if (!base58Encoder2)
|
|
1012
|
+
base58Encoder2 = codecsStrings.getBase58Encoder();
|
|
802
1013
|
if (
|
|
803
1014
|
// Lowest value (64 bytes of zeroes)
|
|
804
1015
|
putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
|
|
@@ -806,37 +1017,32 @@ function isTransactionSignature(putativeTransactionSignature) {
|
|
|
806
1017
|
) {
|
|
807
1018
|
return false;
|
|
808
1019
|
}
|
|
809
|
-
const
|
|
810
|
-
const numBytes =
|
|
1020
|
+
const bytes = base58Encoder2.encode(putativeTransactionSignature);
|
|
1021
|
+
const numBytes = bytes.byteLength;
|
|
811
1022
|
if (numBytes !== 64) {
|
|
812
1023
|
return false;
|
|
813
1024
|
}
|
|
814
1025
|
return true;
|
|
815
1026
|
}
|
|
816
|
-
async function getCompiledMessageSignature(message, secretKey) {
|
|
817
|
-
const wireMessageBytes = getCompiledMessageEncoder().serialize(message);
|
|
818
|
-
const signature = await keys.signBytes(secretKey, wireMessageBytes);
|
|
819
|
-
return signature;
|
|
820
|
-
}
|
|
821
1027
|
function getSignatureFromTransaction(transaction) {
|
|
1028
|
+
if (!base58Decoder)
|
|
1029
|
+
base58Decoder = codecsStrings.getBase58Decoder();
|
|
822
1030
|
const signatureBytes = transaction.signatures[transaction.feePayer];
|
|
823
1031
|
if (!signatureBytes) {
|
|
824
1032
|
throw new Error(
|
|
825
1033
|
"Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
|
|
826
1034
|
);
|
|
827
1035
|
}
|
|
828
|
-
const transactionSignature2 =
|
|
1036
|
+
const transactionSignature2 = base58Decoder.decode(signatureBytes)[0];
|
|
829
1037
|
return transactionSignature2;
|
|
830
1038
|
}
|
|
831
1039
|
async function signTransaction(keyPairs, transaction) {
|
|
832
1040
|
const compiledMessage = compileMessage(transaction);
|
|
833
1041
|
const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
|
|
1042
|
+
const wireMessageBytes = getCompiledMessageEncoder().encode(compiledMessage);
|
|
834
1043
|
const publicKeySignaturePairs = await Promise.all(
|
|
835
1044
|
keyPairs.map(
|
|
836
|
-
(keyPair) => Promise.all([
|
|
837
|
-
addresses.getAddressFromPublicKey(keyPair.publicKey),
|
|
838
|
-
getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
|
|
839
|
-
])
|
|
1045
|
+
(keyPair) => Promise.all([addresses.getAddressFromPublicKey(keyPair.publicKey), keys.signBytes(keyPair.privateKey, wireMessageBytes)])
|
|
840
1046
|
)
|
|
841
1047
|
);
|
|
842
1048
|
for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
|
|
@@ -853,10 +1059,19 @@ function transactionSignature(putativeTransactionSignature) {
|
|
|
853
1059
|
assertIsTransactionSignature(putativeTransactionSignature);
|
|
854
1060
|
return putativeTransactionSignature;
|
|
855
1061
|
}
|
|
1062
|
+
function assertTransactionIsFullySigned(transaction) {
|
|
1063
|
+
const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
|
|
1064
|
+
const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
|
|
1065
|
+
requiredSigners.forEach((address) => {
|
|
1066
|
+
if (!transaction.signatures[address]) {
|
|
1067
|
+
throw new Error(`Transaction is missing signature for address \`${address}\``);
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
856
1071
|
|
|
857
1072
|
// src/wire-transaction.ts
|
|
858
1073
|
function getBase64EncodedWireTransaction(transaction) {
|
|
859
|
-
const wireTransactionBytes = getTransactionEncoder().
|
|
1074
|
+
const wireTransactionBytes = getTransactionEncoder().encode(transaction);
|
|
860
1075
|
{
|
|
861
1076
|
return btoa(String.fromCharCode(...wireTransactionBytes));
|
|
862
1077
|
}
|
|
@@ -866,9 +1081,12 @@ exports.appendTransactionInstruction = appendTransactionInstruction;
|
|
|
866
1081
|
exports.assertIsBlockhash = assertIsBlockhash;
|
|
867
1082
|
exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
|
|
868
1083
|
exports.assertIsTransactionSignature = assertIsTransactionSignature;
|
|
1084
|
+
exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
|
|
869
1085
|
exports.createTransaction = createTransaction;
|
|
870
1086
|
exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
|
|
871
1087
|
exports.getSignatureFromTransaction = getSignatureFromTransaction;
|
|
1088
|
+
exports.getTransactionCodec = getTransactionCodec;
|
|
1089
|
+
exports.getTransactionDecoder = getTransactionDecoder;
|
|
872
1090
|
exports.getTransactionEncoder = getTransactionEncoder;
|
|
873
1091
|
exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
|
|
874
1092
|
exports.isTransactionSignature = isTransactionSignature;
|
|
@@ -878,5 +1096,3 @@ exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockh
|
|
|
878
1096
|
exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
|
|
879
1097
|
exports.signTransaction = signTransaction;
|
|
880
1098
|
exports.transactionSignature = transactionSignature;
|
|
881
|
-
//# sourceMappingURL=out.js.map
|
|
882
|
-
//# sourceMappingURL=index.browser.cjs.map
|