@solana/transactions 2.0.0-experimental.606040b → 2.0.0-experimental.613053d

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 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
@@ -1,15 +1,15 @@
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
- // ../rpc-types/dist/index.browser.js
12
+ // src/blockhash.ts
13
13
  var base58Encoder;
14
14
  function assertIsBlockhash(putativeBlockhash) {
15
15
  if (!base58Encoder)
@@ -62,7 +62,7 @@ function isTransactionWithBlockhashLifetime(transaction) {
62
62
  }
63
63
  function assertIsTransactionWithBlockhashLifetime(transaction) {
64
64
  if (!isTransactionWithBlockhashLifetime(transaction)) {
65
- throw new Error("Transaction does not have a blockhash lifetime");
65
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_EXPECTED_BLOCKHASH_LIFETIME);
66
66
  }
67
67
  }
68
68
  function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
@@ -88,8 +88,6 @@ function createTransaction({
88
88
  Object.freeze(out);
89
89
  return out;
90
90
  }
91
-
92
- // ../instructions/dist/index.browser.js
93
91
  var AccountRole = /* @__PURE__ */ ((AccountRole2) => {
94
92
  AccountRole2[AccountRole2["WRITABLE_SIGNER"] = /* 3 */
95
93
  3] = "WRITABLE_SIGNER";
@@ -111,13 +109,11 @@ function isWritableRole(role) {
111
109
  function mergeRoles(roleA, roleB) {
112
110
  return roleA | roleB;
113
111
  }
114
-
115
- // src/durable-nonce.ts
116
112
  var RECENT_BLOCKHASHES_SYSVAR_ADDRESS = "SysvarRecentB1ockHashes11111111111111111111";
117
113
  var SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
118
114
  function assertIsDurableNonceTransaction(transaction) {
119
115
  if (!isDurableNonceTransaction(transaction)) {
120
- throw new Error("Transaction is not a durable nonce transaction");
116
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_EXPECTED_NONCE_LIFETIME);
121
117
  }
122
118
  }
123
119
  function createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress) {
@@ -203,17 +199,23 @@ function setTransactionFeePayer(feePayer, transaction) {
203
199
 
204
200
  // src/instructions.ts
205
201
  function appendTransactionInstruction(instruction, transaction) {
202
+ return appendTransactionInstructions([instruction], transaction);
203
+ }
204
+ function appendTransactionInstructions(instructions, transaction) {
206
205
  const out = {
207
206
  ...getUnsignedTransaction(transaction),
208
- instructions: [...transaction.instructions, instruction]
207
+ instructions: [...transaction.instructions, ...instructions]
209
208
  };
210
209
  Object.freeze(out);
211
210
  return out;
212
211
  }
213
212
  function prependTransactionInstruction(instruction, transaction) {
213
+ return prependTransactionInstructions([instruction], transaction);
214
+ }
215
+ function prependTransactionInstructions(instructions, transaction) {
214
216
  const out = {
215
217
  ...getUnsignedTransaction(transaction),
216
- instructions: [instruction, ...transaction.instructions]
218
+ instructions: [...instructions, ...transaction.instructions]
217
219
  };
218
220
  Object.freeze(out);
219
221
  return out;
@@ -260,8 +262,9 @@ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTab
260
262
  const compiledAddressTableLookupAddresses = compiledAddressTableLookups.map((l) => l.lookupTableAddress);
261
263
  const missing = compiledAddressTableLookupAddresses.filter((a) => addressesByLookupTableAddress[a] === void 0);
262
264
  if (missing.length > 0) {
263
- const missingAddresses = missing.join(", ");
264
- throw new Error(`Addresses not provided for lookup tables: [${missingAddresses}]`);
265
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING, {
266
+ lookupTableAddresses: missing
267
+ });
265
268
  }
266
269
  const readOnlyMetas = [];
267
270
  const writableMetas = [];
@@ -269,8 +272,13 @@ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTab
269
272
  const addresses = addressesByLookupTableAddress[lookup.lookupTableAddress];
270
273
  const highestIndex = Math.max(...lookup.readableIndices, ...lookup.writableIndices);
271
274
  if (highestIndex >= addresses.length) {
272
- throw new Error(
273
- `Cannot look up index ${highestIndex} in lookup table [${lookup.lookupTableAddress}]. The lookup table may have been extended since the addresses provided were retrieved.`
275
+ throw new errors.SolanaError(
276
+ errors.SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,
277
+ {
278
+ highestKnownIndex: addresses.length - 1,
279
+ highestRequestedIndex: highestIndex,
280
+ lookupTableAddress: lookup.lookupTableAddress
281
+ }
274
282
  );
275
283
  }
276
284
  const readOnlyForLookup = lookup.readableIndices.map((r) => ({
@@ -293,7 +301,9 @@ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTab
293
301
  function convertInstruction(instruction, accountMetas) {
294
302
  const programAddress = accountMetas[instruction.programAddressIndex]?.address;
295
303
  if (!programAddress) {
296
- throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
304
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, {
305
+ index: instruction.programAddressIndex
306
+ });
297
307
  }
298
308
  const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
299
309
  const { data } = instruction;
@@ -338,8 +348,9 @@ function convertSignatures(compiledTransaction) {
338
348
  function decompileTransaction(compiledTransaction, config) {
339
349
  const { compiledMessage } = compiledTransaction;
340
350
  const feePayer = compiledMessage.staticAccounts[0];
341
- if (!feePayer)
342
- throw new Error("No fee payer set in CompiledTransaction");
351
+ if (!feePayer) {
352
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_FAILED_TO_DECOMPILE_FEE_PAYER_MISSING);
353
+ }
343
354
  const accountMetas = getAccountMetas(compiledMessage);
344
355
  const accountLookupMetas = "addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups !== void 0 && compiledMessage.addressTableLookups.length > 0 ? getAddressLookupMetas(compiledMessage.addressTableLookups, config?.addressesByLookupTableAddress ?? {}) : [];
345
356
  const transactionMetas = [...accountMetas, ...accountLookupMetas];
@@ -379,13 +390,13 @@ function getAddressMapFromInstructions(feePayer, instructions) {
379
390
  if (isWritableRole(entry.role)) {
380
391
  switch (entry[TYPE]) {
381
392
  case 0 /* FEE_PAYER */:
382
- throw new Error(
383
- `This transaction includes an address (\`${instruction.programAddress}\`) which is both invoked and set as the fee payer. Program addresses may not pay fees.`
384
- );
393
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_INVOKED_PROGRAMS_CANNOT_PAY_FEES, {
394
+ programAddress: instruction.programAddress
395
+ });
385
396
  default:
386
- throw new Error(
387
- `This transaction includes an address (\`${instruction.programAddress}\`) which is both invoked and marked writable. Program addresses may not be writable.`
388
- );
397
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE, {
398
+ programAddress: instruction.programAddress
399
+ });
389
400
  }
390
401
  }
391
402
  if (entry[TYPE] === 2 /* STATIC */) {
@@ -450,8 +461,11 @@ function getAddressMapFromInstructions(feePayer, instructions) {
450
461
  addressesOfInvokedPrograms.has(account.address)
451
462
  ) {
452
463
  if (isWritableRole(accountMeta.role)) {
453
- throw new Error(
454
- `This transaction includes an address (\`${account.address}\`) which is both invoked and marked writable. Program addresses may not be writable.`
464
+ throw new errors.SolanaError(
465
+ errors.SOLANA_ERROR__TRANSACTION_INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE,
466
+ {
467
+ programAddress: account.address
468
+ }
455
469
  );
456
470
  }
457
471
  if (entry.role !== nextRole) {
@@ -741,7 +755,9 @@ function getTransactionVersionEncoder() {
741
755
  return offset;
742
756
  }
743
757
  if (value < 0 || value > 127) {
744
- throw new Error(`Transaction version must be in the range [0, 127]. \`${value}\` given.`);
758
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_VERSION_NUMBER_OUT_OF_RANGE, {
759
+ actualVersion: value
760
+ });
745
761
  }
746
762
  bytes.set([value | VERSION_FLAG_MASK], offset);
747
763
  return offset + 1;
@@ -828,12 +844,15 @@ function getCompiledMessageEncoder() {
828
844
  });
829
845
  }
830
846
  function getCompiledMessageDecoder() {
831
- return codecsCore.mapDecoder(codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple()), ({ addressTableLookups, ...restOfMessage }) => {
832
- if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
833
- return restOfMessage;
847
+ return codecsCore.mapDecoder(
848
+ codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple()),
849
+ ({ addressTableLookups, ...restOfMessage }) => {
850
+ if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
851
+ return restOfMessage;
852
+ }
853
+ return { ...restOfMessage, addressTableLookups };
834
854
  }
835
- return { ...restOfMessage, addressTableLookups };
836
- });
855
+ );
837
856
  }
838
857
  function getCompiledMessageCodec() {
839
858
  return codecsCore.combineCodec(getCompiledMessageEncoder(), getCompiledMessageDecoder());
@@ -944,6 +963,7 @@ function getBase64EncodedWireTransaction(transaction) {
944
963
  }
945
964
 
946
965
  exports.appendTransactionInstruction = appendTransactionInstruction;
966
+ exports.appendTransactionInstructions = appendTransactionInstructions;
947
967
  exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
948
968
  exports.assertIsTransactionWithBlockhashLifetime = assertIsTransactionWithBlockhashLifetime;
949
969
  exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
@@ -959,9 +979,11 @@ exports.getSignatureFromTransaction = getSignatureFromTransaction;
959
979
  exports.getTransactionCodec = getTransactionCodec;
960
980
  exports.getTransactionDecoder = getTransactionDecoder;
961
981
  exports.getTransactionEncoder = getTransactionEncoder;
982
+ exports.getUnsignedTransaction = getUnsignedTransaction;
962
983
  exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
963
984
  exports.partiallySignTransaction = partiallySignTransaction;
964
985
  exports.prependTransactionInstruction = prependTransactionInstruction;
986
+ exports.prependTransactionInstructions = prependTransactionInstructions;
965
987
  exports.setTransactionFeePayer = setTransactionFeePayer;
966
988
  exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
967
989
  exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;