@solana/transactions 2.0.0-experimental.fd64233 → 2.0.0-experimental.feaeef2
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 +69 -49
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +67 -50
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js +67 -50
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +69 -49
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +67 -50
- 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/package.json +17 -40
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,35 +1,33 @@
|
|
|
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');
|
|
6
7
|
var codecsCore = require('@solana/codecs-core');
|
|
7
8
|
var codecsDataStructures = require('@solana/codecs-data-structures');
|
|
8
9
|
var codecsNumbers = require('@solana/codecs-numbers');
|
|
9
|
-
var errors = require('@solana/errors');
|
|
10
10
|
var keys = require('@solana/keys');
|
|
11
11
|
|
|
12
|
-
//
|
|
12
|
+
// src/blockhash.ts
|
|
13
13
|
var base58Encoder;
|
|
14
14
|
function assertIsBlockhash(putativeBlockhash) {
|
|
15
15
|
if (!base58Encoder)
|
|
16
16
|
base58Encoder = codecsStrings.getBase58Encoder();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
throw new Error(`\`${putativeBlockhash}\` is not a blockhash`, {
|
|
32
|
-
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__INVALID_BLOCKHASH_BYTE_LENGTH, {
|
|
30
|
+
actualLength: numBytes
|
|
33
31
|
});
|
|
34
32
|
}
|
|
35
33
|
}
|
|
@@ -62,7 +60,7 @@ function isTransactionWithBlockhashLifetime(transaction) {
|
|
|
62
60
|
}
|
|
63
61
|
function assertIsTransactionWithBlockhashLifetime(transaction) {
|
|
64
62
|
if (!isTransactionWithBlockhashLifetime(transaction)) {
|
|
65
|
-
throw new
|
|
63
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME);
|
|
66
64
|
}
|
|
67
65
|
}
|
|
68
66
|
function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
|
|
@@ -88,8 +86,6 @@ function createTransaction({
|
|
|
88
86
|
Object.freeze(out);
|
|
89
87
|
return out;
|
|
90
88
|
}
|
|
91
|
-
|
|
92
|
-
// ../instructions/dist/index.browser.js
|
|
93
89
|
var AccountRole = /* @__PURE__ */ ((AccountRole2) => {
|
|
94
90
|
AccountRole2[AccountRole2["WRITABLE_SIGNER"] = /* 3 */
|
|
95
91
|
3] = "WRITABLE_SIGNER";
|
|
@@ -111,13 +107,11 @@ function isWritableRole(role) {
|
|
|
111
107
|
function mergeRoles(roleA, roleB) {
|
|
112
108
|
return roleA | roleB;
|
|
113
109
|
}
|
|
114
|
-
|
|
115
|
-
// src/durable-nonce.ts
|
|
116
110
|
var RECENT_BLOCKHASHES_SYSVAR_ADDRESS = "SysvarRecentB1ockHashes11111111111111111111";
|
|
117
111
|
var SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
|
|
118
112
|
function assertIsDurableNonceTransaction(transaction) {
|
|
119
113
|
if (!isDurableNonceTransaction(transaction)) {
|
|
120
|
-
throw new
|
|
114
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME);
|
|
121
115
|
}
|
|
122
116
|
}
|
|
123
117
|
function createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress) {
|
|
@@ -203,17 +197,23 @@ function setTransactionFeePayer(feePayer, transaction) {
|
|
|
203
197
|
|
|
204
198
|
// src/instructions.ts
|
|
205
199
|
function appendTransactionInstruction(instruction, transaction) {
|
|
200
|
+
return appendTransactionInstructions([instruction], transaction);
|
|
201
|
+
}
|
|
202
|
+
function appendTransactionInstructions(instructions, transaction) {
|
|
206
203
|
const out = {
|
|
207
204
|
...getUnsignedTransaction(transaction),
|
|
208
|
-
instructions: [...transaction.instructions,
|
|
205
|
+
instructions: [...transaction.instructions, ...instructions]
|
|
209
206
|
};
|
|
210
207
|
Object.freeze(out);
|
|
211
208
|
return out;
|
|
212
209
|
}
|
|
213
210
|
function prependTransactionInstruction(instruction, transaction) {
|
|
211
|
+
return prependTransactionInstructions([instruction], transaction);
|
|
212
|
+
}
|
|
213
|
+
function prependTransactionInstructions(instructions, transaction) {
|
|
214
214
|
const out = {
|
|
215
215
|
...getUnsignedTransaction(transaction),
|
|
216
|
-
instructions: [
|
|
216
|
+
instructions: [...instructions, ...transaction.instructions]
|
|
217
217
|
};
|
|
218
218
|
Object.freeze(out);
|
|
219
219
|
return out;
|
|
@@ -260,8 +260,9 @@ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTab
|
|
|
260
260
|
const compiledAddressTableLookupAddresses = compiledAddressTableLookups.map((l) => l.lookupTableAddress);
|
|
261
261
|
const missing = compiledAddressTableLookupAddresses.filter((a) => addressesByLookupTableAddress[a] === void 0);
|
|
262
262
|
if (missing.length > 0) {
|
|
263
|
-
|
|
264
|
-
|
|
263
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING, {
|
|
264
|
+
lookupTableAddresses: missing
|
|
265
|
+
});
|
|
265
266
|
}
|
|
266
267
|
const readOnlyMetas = [];
|
|
267
268
|
const writableMetas = [];
|
|
@@ -269,8 +270,13 @@ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTab
|
|
|
269
270
|
const addresses = addressesByLookupTableAddress[lookup.lookupTableAddress];
|
|
270
271
|
const highestIndex = Math.max(...lookup.readableIndices, ...lookup.writableIndices);
|
|
271
272
|
if (highestIndex >= addresses.length) {
|
|
272
|
-
throw new
|
|
273
|
-
|
|
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
|
+
}
|
|
274
280
|
);
|
|
275
281
|
}
|
|
276
282
|
const readOnlyForLookup = lookup.readableIndices.map((r) => ({
|
|
@@ -293,7 +299,9 @@ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTab
|
|
|
293
299
|
function convertInstruction(instruction, accountMetas) {
|
|
294
300
|
const programAddress = accountMetas[instruction.programAddressIndex]?.address;
|
|
295
301
|
if (!programAddress) {
|
|
296
|
-
throw new
|
|
302
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, {
|
|
303
|
+
index: instruction.programAddressIndex
|
|
304
|
+
});
|
|
297
305
|
}
|
|
298
306
|
const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
|
|
299
307
|
const { data } = instruction;
|
|
@@ -338,8 +346,9 @@ function convertSignatures(compiledTransaction) {
|
|
|
338
346
|
function decompileTransaction(compiledTransaction, config) {
|
|
339
347
|
const { compiledMessage } = compiledTransaction;
|
|
340
348
|
const feePayer = compiledMessage.staticAccounts[0];
|
|
341
|
-
if (!feePayer)
|
|
342
|
-
throw new
|
|
349
|
+
if (!feePayer) {
|
|
350
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_FEE_PAYER_MISSING);
|
|
351
|
+
}
|
|
343
352
|
const accountMetas = getAccountMetas(compiledMessage);
|
|
344
353
|
const accountLookupMetas = "addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups !== void 0 && compiledMessage.addressTableLookups.length > 0 ? getAddressLookupMetas(compiledMessage.addressTableLookups, config?.addressesByLookupTableAddress ?? {}) : [];
|
|
345
354
|
const transactionMetas = [...accountMetas, ...accountLookupMetas];
|
|
@@ -379,13 +388,13 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
379
388
|
if (isWritableRole(entry.role)) {
|
|
380
389
|
switch (entry[TYPE]) {
|
|
381
390
|
case 0 /* FEE_PAYER */:
|
|
382
|
-
throw new
|
|
383
|
-
|
|
384
|
-
);
|
|
391
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES, {
|
|
392
|
+
programAddress: instruction.programAddress
|
|
393
|
+
});
|
|
385
394
|
default:
|
|
386
|
-
throw new
|
|
387
|
-
|
|
388
|
-
);
|
|
395
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE, {
|
|
396
|
+
programAddress: instruction.programAddress
|
|
397
|
+
});
|
|
389
398
|
}
|
|
390
399
|
}
|
|
391
400
|
if (entry[TYPE] === 2 /* STATIC */) {
|
|
@@ -450,8 +459,11 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
450
459
|
addressesOfInvokedPrograms.has(account.address)
|
|
451
460
|
) {
|
|
452
461
|
if (isWritableRole(accountMeta.role)) {
|
|
453
|
-
throw new
|
|
454
|
-
|
|
462
|
+
throw new errors.SolanaError(
|
|
463
|
+
errors.SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE,
|
|
464
|
+
{
|
|
465
|
+
programAddress: account.address
|
|
466
|
+
}
|
|
455
467
|
);
|
|
456
468
|
}
|
|
457
469
|
if (entry.role !== nextRole) {
|
|
@@ -741,7 +753,9 @@ function getTransactionVersionEncoder() {
|
|
|
741
753
|
return offset;
|
|
742
754
|
}
|
|
743
755
|
if (value < 0 || value > 127) {
|
|
744
|
-
throw new
|
|
756
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_OUT_OF_RANGE, {
|
|
757
|
+
actualVersion: value
|
|
758
|
+
});
|
|
745
759
|
}
|
|
746
760
|
bytes.set([value | VERSION_FLAG_MASK], offset);
|
|
747
761
|
return offset + 1;
|
|
@@ -828,12 +842,15 @@ function getCompiledMessageEncoder() {
|
|
|
828
842
|
});
|
|
829
843
|
}
|
|
830
844
|
function getCompiledMessageDecoder() {
|
|
831
|
-
return codecsCore.mapDecoder(
|
|
832
|
-
|
|
833
|
-
|
|
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 };
|
|
834
852
|
}
|
|
835
|
-
|
|
836
|
-
});
|
|
853
|
+
);
|
|
837
854
|
}
|
|
838
855
|
function getCompiledMessageCodec() {
|
|
839
856
|
return codecsCore.combineCodec(getCompiledMessageEncoder(), getCompiledMessageDecoder());
|
|
@@ -893,7 +910,7 @@ function getSignatureFromTransaction(transaction) {
|
|
|
893
910
|
base58Decoder = codecsStrings.getBase58Decoder();
|
|
894
911
|
const signatureBytes = transaction.signatures[transaction.feePayer];
|
|
895
912
|
if (!signatureBytes) {
|
|
896
|
-
throw new errors.SolanaError(errors.
|
|
913
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING);
|
|
897
914
|
}
|
|
898
915
|
const transactionSignature = base58Decoder.decode(signatureBytes);
|
|
899
916
|
return transactionSignature;
|
|
@@ -933,7 +950,7 @@ function assertTransactionIsFullySigned(transaction) {
|
|
|
933
950
|
}
|
|
934
951
|
});
|
|
935
952
|
if (missingSigs.length > 0) {
|
|
936
|
-
throw new errors.SolanaError(errors.
|
|
953
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {
|
|
937
954
|
addresses: missingSigs
|
|
938
955
|
});
|
|
939
956
|
}
|
|
@@ -944,6 +961,7 @@ function getBase64EncodedWireTransaction(transaction) {
|
|
|
944
961
|
}
|
|
945
962
|
|
|
946
963
|
exports.appendTransactionInstruction = appendTransactionInstruction;
|
|
964
|
+
exports.appendTransactionInstructions = appendTransactionInstructions;
|
|
947
965
|
exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
|
|
948
966
|
exports.assertIsTransactionWithBlockhashLifetime = assertIsTransactionWithBlockhashLifetime;
|
|
949
967
|
exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
|
|
@@ -959,9 +977,11 @@ exports.getSignatureFromTransaction = getSignatureFromTransaction;
|
|
|
959
977
|
exports.getTransactionCodec = getTransactionCodec;
|
|
960
978
|
exports.getTransactionDecoder = getTransactionDecoder;
|
|
961
979
|
exports.getTransactionEncoder = getTransactionEncoder;
|
|
980
|
+
exports.getUnsignedTransaction = getUnsignedTransaction;
|
|
962
981
|
exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
|
|
963
982
|
exports.partiallySignTransaction = partiallySignTransaction;
|
|
964
983
|
exports.prependTransactionInstruction = prependTransactionInstruction;
|
|
984
|
+
exports.prependTransactionInstructions = prependTransactionInstructions;
|
|
965
985
|
exports.setTransactionFeePayer = setTransactionFeePayer;
|
|
966
986
|
exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
|
|
967
987
|
exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
|