@solana/transactions 2.0.0-experimental.098806e → 2.0.0-experimental.0af01ac
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 +7 -3
- package/dist/index.browser.cjs +71 -50
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +69 -51
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js +69 -51
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +71 -50
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +69 -51
- package/dist/index.node.js.map +1 -1
- package/dist/types/accounts.d.ts.map +1 -1
- package/dist/types/blockhash.d.ts.map +1 -1
- package/dist/types/decompile-transaction.d.ts.map +1 -1
- package/dist/types/durable-nonce.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/instructions.d.ts +2 -0
- package/dist/types/instructions.d.ts.map +1 -1
- package/dist/types/serializers/message.d.ts.map +1 -1
- package/dist/types/serializers/transaction-version.d.ts.map +1 -1
- package/dist/types/signatures.d.ts.map +1 -1
- package/package.json +17 -39
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ const transferTransaction = pipe(
|
|
|
30
30
|
createTransaction({ version: 0 }),
|
|
31
31
|
tx => setTransactionFeePayer(myAddress, tx),
|
|
32
32
|
tx => setTransactionLifetimeUsingBlockhash(latestBlockhash, tx),
|
|
33
|
-
tx => appendTransactionInstruction(createTransferInstruction(myAddress, toAddress, amountInLamports), tx)
|
|
33
|
+
tx => appendTransactionInstruction(createTransferInstruction(myAddress, toAddress, amountInLamports), tx),
|
|
34
34
|
);
|
|
35
35
|
```
|
|
36
36
|
|
|
@@ -144,7 +144,7 @@ const nonce =
|
|
|
144
144
|
|
|
145
145
|
const durableNonceTransaction = setTransactionLifetimeUsingDurableNonce(
|
|
146
146
|
{ nonce, nonceAccountAddress, nonceAuthorityAddress },
|
|
147
|
-
tx
|
|
147
|
+
tx,
|
|
148
148
|
);
|
|
149
149
|
```
|
|
150
150
|
|
|
@@ -210,14 +210,18 @@ const memoTransaction = appendTransactionInstruction(
|
|
|
210
210
|
data: new TextEncoder().encode('Hello world!'),
|
|
211
211
|
programAddress: address('MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'),
|
|
212
212
|
},
|
|
213
|
-
tx
|
|
213
|
+
tx,
|
|
214
214
|
);
|
|
215
215
|
```
|
|
216
216
|
|
|
217
|
+
If you'd like to add multiple instructions to a transaction at once, you may use the `appendTransactionInstructions` function instead which accepts an array of instructions.
|
|
218
|
+
|
|
217
219
|
#### `prependTransactionInstruction()`
|
|
218
220
|
|
|
219
221
|
Given an instruction, this method will return a new transaction with that instruction having been added to the beginning of the list of existing instructions.
|
|
220
222
|
|
|
223
|
+
If you'd like to prepend multiple instructions to a transaction at once, you may use the `prependTransactionInstructions` function instead which accepts an array of instructions.
|
|
224
|
+
|
|
221
225
|
See [`appendTransactionInstruction()`](#appendtransactioninstruction) for an example of how to use this function.
|
|
222
226
|
|
|
223
227
|
## Signing transactions
|
package/dist/index.browser.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var errors = require('@solana/errors');
|
|
3
4
|
var codecsStrings = require('@solana/codecs-strings');
|
|
4
5
|
var addresses = require('@solana/addresses');
|
|
5
6
|
var functional = require('@solana/functional');
|
|
@@ -8,27 +9,25 @@ var codecsDataStructures = require('@solana/codecs-data-structures');
|
|
|
8
9
|
var codecsNumbers = require('@solana/codecs-numbers');
|
|
9
10
|
var keys = require('@solana/keys');
|
|
10
11
|
|
|
11
|
-
//
|
|
12
|
+
// src/blockhash.ts
|
|
12
13
|
var base58Encoder;
|
|
13
14
|
function assertIsBlockhash(putativeBlockhash) {
|
|
14
15
|
if (!base58Encoder)
|
|
15
16
|
base58Encoder = codecsStrings.getBase58Encoder();
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
throw new Error(`\`${putativeBlockhash}\` is not a blockhash`, {
|
|
31
|
-
cause: e
|
|
17
|
+
if (
|
|
18
|
+
// Lowest value (32 bytes of zeroes)
|
|
19
|
+
putativeBlockhash.length < 32 || // Highest value (32 bytes of 255)
|
|
20
|
+
putativeBlockhash.length > 44
|
|
21
|
+
) {
|
|
22
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE, {
|
|
23
|
+
actualLength: putativeBlockhash.length
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const bytes = base58Encoder.encode(putativeBlockhash);
|
|
27
|
+
const numBytes = bytes.byteLength;
|
|
28
|
+
if (numBytes !== 32) {
|
|
29
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__BLOCKHASH_BYTE_LENGTH_OUT_OF_RANGE, {
|
|
30
|
+
actualLength: numBytes
|
|
32
31
|
});
|
|
33
32
|
}
|
|
34
33
|
}
|
|
@@ -61,7 +60,7 @@ function isTransactionWithBlockhashLifetime(transaction) {
|
|
|
61
60
|
}
|
|
62
61
|
function assertIsTransactionWithBlockhashLifetime(transaction) {
|
|
63
62
|
if (!isTransactionWithBlockhashLifetime(transaction)) {
|
|
64
|
-
throw new
|
|
63
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_EXPECTED_BLOCKHASH_LIFETIME);
|
|
65
64
|
}
|
|
66
65
|
}
|
|
67
66
|
function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
|
|
@@ -87,8 +86,6 @@ function createTransaction({
|
|
|
87
86
|
Object.freeze(out);
|
|
88
87
|
return out;
|
|
89
88
|
}
|
|
90
|
-
|
|
91
|
-
// ../instructions/dist/index.browser.js
|
|
92
89
|
var AccountRole = /* @__PURE__ */ ((AccountRole2) => {
|
|
93
90
|
AccountRole2[AccountRole2["WRITABLE_SIGNER"] = /* 3 */
|
|
94
91
|
3] = "WRITABLE_SIGNER";
|
|
@@ -110,13 +107,11 @@ function isWritableRole(role) {
|
|
|
110
107
|
function mergeRoles(roleA, roleB) {
|
|
111
108
|
return roleA | roleB;
|
|
112
109
|
}
|
|
113
|
-
|
|
114
|
-
// src/durable-nonce.ts
|
|
115
110
|
var RECENT_BLOCKHASHES_SYSVAR_ADDRESS = "SysvarRecentB1ockHashes11111111111111111111";
|
|
116
111
|
var SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
|
|
117
112
|
function assertIsDurableNonceTransaction(transaction) {
|
|
118
113
|
if (!isDurableNonceTransaction(transaction)) {
|
|
119
|
-
throw new
|
|
114
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_EXPECTED_NONCE_LIFETIME);
|
|
120
115
|
}
|
|
121
116
|
}
|
|
122
117
|
function createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress) {
|
|
@@ -202,17 +197,23 @@ function setTransactionFeePayer(feePayer, transaction) {
|
|
|
202
197
|
|
|
203
198
|
// src/instructions.ts
|
|
204
199
|
function appendTransactionInstruction(instruction, transaction) {
|
|
200
|
+
return appendTransactionInstructions([instruction], transaction);
|
|
201
|
+
}
|
|
202
|
+
function appendTransactionInstructions(instructions, transaction) {
|
|
205
203
|
const out = {
|
|
206
204
|
...getUnsignedTransaction(transaction),
|
|
207
|
-
instructions: [...transaction.instructions,
|
|
205
|
+
instructions: [...transaction.instructions, ...instructions]
|
|
208
206
|
};
|
|
209
207
|
Object.freeze(out);
|
|
210
208
|
return out;
|
|
211
209
|
}
|
|
212
210
|
function prependTransactionInstruction(instruction, transaction) {
|
|
211
|
+
return prependTransactionInstructions([instruction], transaction);
|
|
212
|
+
}
|
|
213
|
+
function prependTransactionInstructions(instructions, transaction) {
|
|
213
214
|
const out = {
|
|
214
215
|
...getUnsignedTransaction(transaction),
|
|
215
|
-
instructions: [
|
|
216
|
+
instructions: [...instructions, ...transaction.instructions]
|
|
216
217
|
};
|
|
217
218
|
Object.freeze(out);
|
|
218
219
|
return out;
|
|
@@ -259,8 +260,9 @@ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTab
|
|
|
259
260
|
const compiledAddressTableLookupAddresses = compiledAddressTableLookups.map((l) => l.lookupTableAddress);
|
|
260
261
|
const missing = compiledAddressTableLookupAddresses.filter((a) => addressesByLookupTableAddress[a] === void 0);
|
|
261
262
|
if (missing.length > 0) {
|
|
262
|
-
|
|
263
|
-
|
|
263
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING, {
|
|
264
|
+
lookupTableAddresses: missing
|
|
265
|
+
});
|
|
264
266
|
}
|
|
265
267
|
const readOnlyMetas = [];
|
|
266
268
|
const writableMetas = [];
|
|
@@ -268,8 +270,13 @@ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTab
|
|
|
268
270
|
const addresses = addressesByLookupTableAddress[lookup.lookupTableAddress];
|
|
269
271
|
const highestIndex = Math.max(...lookup.readableIndices, ...lookup.writableIndices);
|
|
270
272
|
if (highestIndex >= addresses.length) {
|
|
271
|
-
throw new
|
|
272
|
-
|
|
273
|
+
throw new errors.SolanaError(
|
|
274
|
+
errors.SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,
|
|
275
|
+
{
|
|
276
|
+
highestKnownIndex: addresses.length - 1,
|
|
277
|
+
highestRequestedIndex: highestIndex,
|
|
278
|
+
lookupTableAddress: lookup.lookupTableAddress
|
|
279
|
+
}
|
|
273
280
|
);
|
|
274
281
|
}
|
|
275
282
|
const readOnlyForLookup = lookup.readableIndices.map((r) => ({
|
|
@@ -292,7 +299,9 @@ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTab
|
|
|
292
299
|
function convertInstruction(instruction, accountMetas) {
|
|
293
300
|
const programAddress = accountMetas[instruction.programAddressIndex]?.address;
|
|
294
301
|
if (!programAddress) {
|
|
295
|
-
throw new
|
|
302
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, {
|
|
303
|
+
index: instruction.programAddressIndex
|
|
304
|
+
});
|
|
296
305
|
}
|
|
297
306
|
const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
|
|
298
307
|
const { data } = instruction;
|
|
@@ -337,8 +346,9 @@ function convertSignatures(compiledTransaction) {
|
|
|
337
346
|
function decompileTransaction(compiledTransaction, config) {
|
|
338
347
|
const { compiledMessage } = compiledTransaction;
|
|
339
348
|
const feePayer = compiledMessage.staticAccounts[0];
|
|
340
|
-
if (!feePayer)
|
|
341
|
-
throw new
|
|
349
|
+
if (!feePayer) {
|
|
350
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_FEE_PAYER_MISSING);
|
|
351
|
+
}
|
|
342
352
|
const accountMetas = getAccountMetas(compiledMessage);
|
|
343
353
|
const accountLookupMetas = "addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups !== void 0 && compiledMessage.addressTableLookups.length > 0 ? getAddressLookupMetas(compiledMessage.addressTableLookups, config?.addressesByLookupTableAddress ?? {}) : [];
|
|
344
354
|
const transactionMetas = [...accountMetas, ...accountLookupMetas];
|
|
@@ -378,13 +388,13 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
378
388
|
if (isWritableRole(entry.role)) {
|
|
379
389
|
switch (entry[TYPE]) {
|
|
380
390
|
case 0 /* FEE_PAYER */:
|
|
381
|
-
throw new
|
|
382
|
-
|
|
383
|
-
);
|
|
391
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_INVOKED_PROGRAMS_CANNOT_PAY_FEES, {
|
|
392
|
+
programAddress: instruction.programAddress
|
|
393
|
+
});
|
|
384
394
|
default:
|
|
385
|
-
throw new
|
|
386
|
-
|
|
387
|
-
);
|
|
395
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE, {
|
|
396
|
+
programAddress: instruction.programAddress
|
|
397
|
+
});
|
|
388
398
|
}
|
|
389
399
|
}
|
|
390
400
|
if (entry[TYPE] === 2 /* STATIC */) {
|
|
@@ -449,8 +459,11 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
449
459
|
addressesOfInvokedPrograms.has(account.address)
|
|
450
460
|
) {
|
|
451
461
|
if (isWritableRole(accountMeta.role)) {
|
|
452
|
-
throw new
|
|
453
|
-
|
|
462
|
+
throw new errors.SolanaError(
|
|
463
|
+
errors.SOLANA_ERROR__TRANSACTION_INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE,
|
|
464
|
+
{
|
|
465
|
+
programAddress: account.address
|
|
466
|
+
}
|
|
454
467
|
);
|
|
455
468
|
}
|
|
456
469
|
if (entry.role !== nextRole) {
|
|
@@ -740,7 +753,9 @@ function getTransactionVersionEncoder() {
|
|
|
740
753
|
return offset;
|
|
741
754
|
}
|
|
742
755
|
if (value < 0 || value > 127) {
|
|
743
|
-
throw new
|
|
756
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_VERSION_NUMBER_OUT_OF_RANGE, {
|
|
757
|
+
actualVersion: value
|
|
758
|
+
});
|
|
744
759
|
}
|
|
745
760
|
bytes.set([value | VERSION_FLAG_MASK], offset);
|
|
746
761
|
return offset + 1;
|
|
@@ -827,12 +842,15 @@ function getCompiledMessageEncoder() {
|
|
|
827
842
|
});
|
|
828
843
|
}
|
|
829
844
|
function getCompiledMessageDecoder() {
|
|
830
|
-
return codecsCore.mapDecoder(
|
|
831
|
-
|
|
832
|
-
|
|
845
|
+
return codecsCore.mapDecoder(
|
|
846
|
+
codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple()),
|
|
847
|
+
({ addressTableLookups, ...restOfMessage }) => {
|
|
848
|
+
if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
|
|
849
|
+
return restOfMessage;
|
|
850
|
+
}
|
|
851
|
+
return { ...restOfMessage, addressTableLookups };
|
|
833
852
|
}
|
|
834
|
-
|
|
835
|
-
});
|
|
853
|
+
);
|
|
836
854
|
}
|
|
837
855
|
function getCompiledMessageCodec() {
|
|
838
856
|
return codecsCore.combineCodec(getCompiledMessageEncoder(), getCompiledMessageDecoder());
|
|
@@ -892,9 +910,7 @@ function getSignatureFromTransaction(transaction) {
|
|
|
892
910
|
base58Decoder = codecsStrings.getBase58Decoder();
|
|
893
911
|
const signatureBytes = transaction.signatures[transaction.feePayer];
|
|
894
912
|
if (!signatureBytes) {
|
|
895
|
-
throw new
|
|
896
|
-
"Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
|
|
897
|
-
);
|
|
913
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_SIGNATURE_NOT_COMPUTABLE);
|
|
898
914
|
}
|
|
899
915
|
const transactionSignature = base58Decoder.decode(signatureBytes);
|
|
900
916
|
return transactionSignature;
|
|
@@ -934,7 +950,9 @@ function assertTransactionIsFullySigned(transaction) {
|
|
|
934
950
|
}
|
|
935
951
|
});
|
|
936
952
|
if (missingSigs.length > 0) {
|
|
937
|
-
throw new
|
|
953
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_MISSING_SIGNATURES, {
|
|
954
|
+
addresses: missingSigs
|
|
955
|
+
});
|
|
938
956
|
}
|
|
939
957
|
}
|
|
940
958
|
function getBase64EncodedWireTransaction(transaction) {
|
|
@@ -943,6 +961,7 @@ function getBase64EncodedWireTransaction(transaction) {
|
|
|
943
961
|
}
|
|
944
962
|
|
|
945
963
|
exports.appendTransactionInstruction = appendTransactionInstruction;
|
|
964
|
+
exports.appendTransactionInstructions = appendTransactionInstructions;
|
|
946
965
|
exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
|
|
947
966
|
exports.assertIsTransactionWithBlockhashLifetime = assertIsTransactionWithBlockhashLifetime;
|
|
948
967
|
exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
|
|
@@ -958,9 +977,11 @@ exports.getSignatureFromTransaction = getSignatureFromTransaction;
|
|
|
958
977
|
exports.getTransactionCodec = getTransactionCodec;
|
|
959
978
|
exports.getTransactionDecoder = getTransactionDecoder;
|
|
960
979
|
exports.getTransactionEncoder = getTransactionEncoder;
|
|
980
|
+
exports.getUnsignedTransaction = getUnsignedTransaction;
|
|
961
981
|
exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
|
|
962
982
|
exports.partiallySignTransaction = partiallySignTransaction;
|
|
963
983
|
exports.prependTransactionInstruction = prependTransactionInstruction;
|
|
984
|
+
exports.prependTransactionInstructions = prependTransactionInstructions;
|
|
964
985
|
exports.setTransactionFeePayer = setTransactionFeePayer;
|
|
965
986
|
exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
|
|
966
987
|
exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
|