@solana/transactions 2.0.0-experimental.ab12c29 → 2.0.0-experimental.ac2c1c8

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.
Files changed (51) hide show
  1. package/README.md +7 -3
  2. package/dist/index.browser.cjs +301 -384
  3. package/dist/index.browser.cjs.map +1 -1
  4. package/dist/index.browser.js +300 -388
  5. package/dist/index.browser.js.map +1 -1
  6. package/dist/index.native.js +300 -388
  7. package/dist/index.native.js.map +1 -1
  8. package/dist/index.node.cjs +303 -384
  9. package/dist/index.node.cjs.map +1 -1
  10. package/dist/index.node.js +302 -388
  11. package/dist/index.node.js.map +1 -1
  12. package/dist/types/blockhash.d.ts +5 -7
  13. package/dist/types/blockhash.d.ts.map +1 -1
  14. package/dist/types/compilable-transaction.d.ts +4 -4
  15. package/dist/types/compile-address-table-lookups.d.ts +1 -1
  16. package/dist/types/compile-header.d.ts +1 -1
  17. package/dist/types/compile-instructions.d.ts +1 -1
  18. package/dist/types/compile-lifetime-token.d.ts +1 -1
  19. package/dist/types/compile-static-accounts.d.ts +1 -1
  20. package/dist/types/compile-transaction.d.ts +3 -3
  21. package/dist/types/create-transaction.d.ts +1 -1
  22. package/dist/types/decompile-transaction.d.ts +12 -4
  23. package/dist/types/decompile-transaction.d.ts.map +1 -1
  24. package/dist/types/durable-nonce.d.ts +2 -2
  25. package/dist/types/fee-payer.d.ts +2 -2
  26. package/dist/types/index.d.ts +13 -11
  27. package/dist/types/index.d.ts.map +1 -1
  28. package/dist/types/instructions.d.ts +4 -2
  29. package/dist/types/instructions.d.ts.map +1 -1
  30. package/dist/types/message.d.ts +6 -6
  31. package/dist/types/serializers/address-table-lookup.d.ts +5 -5
  32. package/dist/types/serializers/address-table-lookup.d.ts.map +1 -1
  33. package/dist/types/serializers/header.d.ts +5 -5
  34. package/dist/types/serializers/header.d.ts.map +1 -1
  35. package/dist/types/serializers/index.d.ts +2 -2
  36. package/dist/types/serializers/instruction.d.ts +5 -5
  37. package/dist/types/serializers/instruction.d.ts.map +1 -1
  38. package/dist/types/serializers/message.d.ts +5 -5
  39. package/dist/types/serializers/message.d.ts.map +1 -1
  40. package/dist/types/serializers/transaction-version.d.ts +5 -5
  41. package/dist/types/serializers/transaction-version.d.ts.map +1 -1
  42. package/dist/types/serializers/transaction.d.ts +9 -6
  43. package/dist/types/serializers/transaction.d.ts.map +1 -1
  44. package/dist/types/signatures.d.ts +2 -2
  45. package/dist/types/signatures.d.ts.map +1 -1
  46. package/dist/types/unsigned-transaction.d.ts +1 -1
  47. package/dist/types/wire-transaction.d.ts +1 -1
  48. package/package.json +18 -39
  49. package/dist/index.development.js +0 -1783
  50. package/dist/index.development.js.map +0 -1
  51. package/dist/index.production.min.js +0 -31
@@ -2,30 +2,14 @@
2
2
 
3
3
  var codecsStrings = require('@solana/codecs-strings');
4
4
  var addresses = require('@solana/addresses');
5
+ var functional = require('@solana/functional');
5
6
  var codecsCore = require('@solana/codecs-core');
6
7
  var codecsDataStructures = require('@solana/codecs-data-structures');
7
8
  var codecsNumbers = require('@solana/codecs-numbers');
8
- var functional = require('@solana/functional');
9
+ var errors = require('@solana/errors');
9
10
  var keys = require('@solana/keys');
10
11
 
11
- // ../build-scripts/env-shim.ts
12
- var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
13
-
14
- // src/unsigned-transaction.ts
15
- function getUnsignedTransaction(transaction) {
16
- if ("signatures" in transaction) {
17
- const {
18
- signatures: _,
19
- // eslint-disable-line @typescript-eslint/no-unused-vars
20
- ...unsignedTransaction
21
- } = transaction;
22
- return unsignedTransaction;
23
- } else {
24
- return transaction;
25
- }
26
- }
27
-
28
- // src/blockhash.ts
12
+ // ../rpc-types/dist/index.browser.js
29
13
  var base58Encoder;
30
14
  function assertIsBlockhash(putativeBlockhash) {
31
15
  if (!base58Encoder)
@@ -49,6 +33,38 @@ function assertIsBlockhash(putativeBlockhash) {
49
33
  });
50
34
  }
51
35
  }
36
+
37
+ // src/unsigned-transaction.ts
38
+ function getUnsignedTransaction(transaction) {
39
+ if ("signatures" in transaction) {
40
+ const {
41
+ signatures: _,
42
+ // eslint-disable-line @typescript-eslint/no-unused-vars
43
+ ...unsignedTransaction
44
+ } = transaction;
45
+ return unsignedTransaction;
46
+ } else {
47
+ return transaction;
48
+ }
49
+ }
50
+
51
+ // src/blockhash.ts
52
+ function isTransactionWithBlockhashLifetime(transaction) {
53
+ const lifetimeConstraintShapeMatches = "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.blockhash === "string" && typeof transaction.lifetimeConstraint.lastValidBlockHeight === "bigint";
54
+ if (!lifetimeConstraintShapeMatches)
55
+ return false;
56
+ try {
57
+ assertIsBlockhash(transaction.lifetimeConstraint.blockhash);
58
+ return true;
59
+ } catch {
60
+ return false;
61
+ }
62
+ }
63
+ function assertIsTransactionWithBlockhashLifetime(transaction) {
64
+ if (!isTransactionWithBlockhashLifetime(transaction)) {
65
+ throw new Error("Transaction does not have a blockhash lifetime");
66
+ }
67
+ }
52
68
  function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
53
69
  if ("lifetimeConstraint" in transaction && transaction.lifetimeConstraint.blockhash === blockhashLifetimeConstraint.blockhash && transaction.lifetimeConstraint.lastValidBlockHeight === blockhashLifetimeConstraint.lastValidBlockHeight) {
54
70
  return transaction;
@@ -187,21 +203,172 @@ function setTransactionFeePayer(feePayer, transaction) {
187
203
 
188
204
  // src/instructions.ts
189
205
  function appendTransactionInstruction(instruction, transaction) {
206
+ return appendTransactionInstructions([instruction], transaction);
207
+ }
208
+ function appendTransactionInstructions(instructions, transaction) {
190
209
  const out = {
191
210
  ...getUnsignedTransaction(transaction),
192
- instructions: [...transaction.instructions, instruction]
211
+ instructions: [...transaction.instructions, ...instructions]
193
212
  };
194
213
  Object.freeze(out);
195
214
  return out;
196
215
  }
197
216
  function prependTransactionInstruction(instruction, transaction) {
217
+ return prependTransactionInstructions([instruction], transaction);
218
+ }
219
+ function prependTransactionInstructions(instructions, transaction) {
198
220
  const out = {
199
221
  ...getUnsignedTransaction(transaction),
200
- instructions: [instruction, ...transaction.instructions]
222
+ instructions: [...instructions, ...transaction.instructions]
201
223
  };
202
224
  Object.freeze(out);
203
225
  return out;
204
226
  }
227
+
228
+ // src/decompile-transaction.ts
229
+ function getAccountMetas(message) {
230
+ const { header } = message;
231
+ const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
232
+ const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
233
+ const accountMetas = [];
234
+ let accountIndex = 0;
235
+ for (let i = 0; i < numWritableSignerAccounts; i++) {
236
+ accountMetas.push({
237
+ address: message.staticAccounts[accountIndex],
238
+ role: AccountRole.WRITABLE_SIGNER
239
+ });
240
+ accountIndex++;
241
+ }
242
+ for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
243
+ accountMetas.push({
244
+ address: message.staticAccounts[accountIndex],
245
+ role: AccountRole.READONLY_SIGNER
246
+ });
247
+ accountIndex++;
248
+ }
249
+ for (let i = 0; i < numWritableNonSignerAccounts; i++) {
250
+ accountMetas.push({
251
+ address: message.staticAccounts[accountIndex],
252
+ role: AccountRole.WRITABLE
253
+ });
254
+ accountIndex++;
255
+ }
256
+ for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
257
+ accountMetas.push({
258
+ address: message.staticAccounts[accountIndex],
259
+ role: AccountRole.READONLY
260
+ });
261
+ accountIndex++;
262
+ }
263
+ return accountMetas;
264
+ }
265
+ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress) {
266
+ const compiledAddressTableLookupAddresses = compiledAddressTableLookups.map((l) => l.lookupTableAddress);
267
+ const missing = compiledAddressTableLookupAddresses.filter((a) => addressesByLookupTableAddress[a] === void 0);
268
+ if (missing.length > 0) {
269
+ const missingAddresses = missing.join(", ");
270
+ throw new Error(`Addresses not provided for lookup tables: [${missingAddresses}]`);
271
+ }
272
+ const readOnlyMetas = [];
273
+ const writableMetas = [];
274
+ for (const lookup of compiledAddressTableLookups) {
275
+ const addresses = addressesByLookupTableAddress[lookup.lookupTableAddress];
276
+ const highestIndex = Math.max(...lookup.readableIndices, ...lookup.writableIndices);
277
+ if (highestIndex >= addresses.length) {
278
+ throw new Error(
279
+ `Cannot look up index ${highestIndex} in lookup table [${lookup.lookupTableAddress}]. The lookup table may have been extended since the addresses provided were retrieved.`
280
+ );
281
+ }
282
+ const readOnlyForLookup = lookup.readableIndices.map((r) => ({
283
+ address: addresses[r],
284
+ addressIndex: r,
285
+ lookupTableAddress: lookup.lookupTableAddress,
286
+ role: AccountRole.READONLY
287
+ }));
288
+ readOnlyMetas.push(...readOnlyForLookup);
289
+ const writableForLookup = lookup.writableIndices.map((w) => ({
290
+ address: addresses[w],
291
+ addressIndex: w,
292
+ lookupTableAddress: lookup.lookupTableAddress,
293
+ role: AccountRole.WRITABLE
294
+ }));
295
+ writableMetas.push(...writableForLookup);
296
+ }
297
+ return [...writableMetas, ...readOnlyMetas];
298
+ }
299
+ function convertInstruction(instruction, accountMetas) {
300
+ const programAddress = accountMetas[instruction.programAddressIndex]?.address;
301
+ if (!programAddress) {
302
+ throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
303
+ }
304
+ const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
305
+ const { data } = instruction;
306
+ return {
307
+ programAddress,
308
+ ...accounts && accounts.length ? { accounts } : {},
309
+ ...data && data.length ? { data } : {}
310
+ };
311
+ }
312
+ function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
313
+ if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
314
+ return {
315
+ blockhash: messageLifetimeToken,
316
+ lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
317
+ // U64 MAX
318
+ };
319
+ } else {
320
+ const nonceAccountAddress = firstInstruction.accounts[0].address;
321
+ addresses.assertIsAddress(nonceAccountAddress);
322
+ const nonceAuthorityAddress = firstInstruction.accounts[2].address;
323
+ addresses.assertIsAddress(nonceAuthorityAddress);
324
+ return {
325
+ nonce: messageLifetimeToken,
326
+ nonceAccountAddress,
327
+ nonceAuthorityAddress
328
+ };
329
+ }
330
+ }
331
+ function convertSignatures(compiledTransaction) {
332
+ const {
333
+ compiledMessage: { staticAccounts },
334
+ signatures
335
+ } = compiledTransaction;
336
+ return signatures.reduce((acc, sig, index) => {
337
+ const allZeros = sig.every((byte) => byte === 0);
338
+ if (allZeros)
339
+ return acc;
340
+ const address = staticAccounts[index];
341
+ return { ...acc, [address]: sig };
342
+ }, {});
343
+ }
344
+ function decompileTransaction(compiledTransaction, config) {
345
+ const { compiledMessage } = compiledTransaction;
346
+ const feePayer = compiledMessage.staticAccounts[0];
347
+ if (!feePayer)
348
+ throw new Error("No fee payer set in CompiledTransaction");
349
+ const accountMetas = getAccountMetas(compiledMessage);
350
+ const accountLookupMetas = "addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups !== void 0 && compiledMessage.addressTableLookups.length > 0 ? getAddressLookupMetas(compiledMessage.addressTableLookups, config?.addressesByLookupTableAddress ?? {}) : [];
351
+ const transactionMetas = [...accountMetas, ...accountLookupMetas];
352
+ const instructions = compiledMessage.instructions.map(
353
+ (compiledInstruction) => convertInstruction(compiledInstruction, transactionMetas)
354
+ );
355
+ const firstInstruction = instructions[0];
356
+ const lifetimeConstraint = getLifetimeConstraint(
357
+ compiledMessage.lifetimeToken,
358
+ firstInstruction,
359
+ config?.lastValidBlockHeight
360
+ );
361
+ const signatures = convertSignatures(compiledTransaction);
362
+ return functional.pipe(
363
+ createTransaction({ version: compiledMessage.version }),
364
+ (tx) => setTransactionFeePayer(feePayer, tx),
365
+ (tx) => instructions.reduce((acc, instruction) => {
366
+ return appendTransactionInstruction(instruction, acc);
367
+ }, tx),
368
+ (tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
369
+ (tx) => Object.keys(signatures).length > 0 ? { ...tx, signatures } : tx
370
+ );
371
+ }
205
372
  function upsert(addressMap, address, update) {
206
373
  addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
207
374
  }
@@ -467,59 +634,31 @@ function compileMessage(transaction) {
467
634
  version: transaction.version
468
635
  };
469
636
  }
470
- var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
471
- var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
472
- var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
473
- var addressTableLookupDescription = __DEV__ ? "A pointer to the address of an address lookup table, along with the readonly/writeable indices of the addresses that should be loaded from it" : "addressTableLookup";
474
637
  var memoizedAddressTableLookupEncoder;
475
638
  function getAddressTableLookupEncoder() {
476
639
  if (!memoizedAddressTableLookupEncoder) {
477
- memoizedAddressTableLookupEncoder = codecsDataStructures.getStructEncoder(
640
+ memoizedAddressTableLookupEncoder = codecsDataStructures.getStructEncoder([
641
+ ["lookupTableAddress", addresses.getAddressEncoder()],
478
642
  [
479
- ["lookupTableAddress", addresses.getAddressEncoder({ description: lookupTableAddressDescription })],
480
- [
481
- "writableIndices",
482
- codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), {
483
- description: writableIndicesDescription,
484
- size: codecsNumbers.getShortU16Encoder()
485
- })
486
- ],
487
- [
488
- "readableIndices",
489
- codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), {
490
- description: readableIndicesDescription,
491
- size: codecsNumbers.getShortU16Encoder()
492
- })
493
- ]
643
+ "writableIndices",
644
+ codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), { size: codecsNumbers.getShortU16Encoder() })
494
645
  ],
495
- { description: addressTableLookupDescription }
496
- );
646
+ [
647
+ "readableIndices",
648
+ codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), { size: codecsNumbers.getShortU16Encoder() })
649
+ ]
650
+ ]);
497
651
  }
498
652
  return memoizedAddressTableLookupEncoder;
499
653
  }
500
654
  var memoizedAddressTableLookupDecoder;
501
655
  function getAddressTableLookupDecoder() {
502
656
  if (!memoizedAddressTableLookupDecoder) {
503
- memoizedAddressTableLookupDecoder = codecsDataStructures.getStructDecoder(
504
- [
505
- ["lookupTableAddress", addresses.getAddressDecoder({ description: lookupTableAddressDescription })],
506
- [
507
- "writableIndices",
508
- codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), {
509
- description: writableIndicesDescription,
510
- size: codecsNumbers.getShortU16Decoder()
511
- })
512
- ],
513
- [
514
- "readableIndices",
515
- codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), {
516
- description: readableIndicesDescription,
517
- size: codecsNumbers.getShortU16Decoder()
518
- })
519
- ]
520
- ],
521
- { description: addressTableLookupDescription }
522
- );
657
+ memoizedAddressTableLookupDecoder = codecsDataStructures.getStructDecoder([
658
+ ["lookupTableAddress", addresses.getAddressDecoder()],
659
+ ["writableIndices", codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), { size: codecsNumbers.getShortU16Decoder() })],
660
+ ["readableIndices", codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), { size: codecsNumbers.getShortU16Decoder() })]
661
+ ]);
523
662
  }
524
663
  return memoizedAddressTableLookupDecoder;
525
664
  }
@@ -529,72 +668,34 @@ function getMemoizedU8Encoder() {
529
668
  memoizedU8Encoder = codecsNumbers.getU8Encoder();
530
669
  return memoizedU8Encoder;
531
670
  }
532
- function getMemoizedU8EncoderDescription(description) {
533
- const encoder = getMemoizedU8Encoder();
534
- return {
535
- ...encoder,
536
- description: description ?? encoder.description
537
- };
538
- }
539
671
  var memoizedU8Decoder;
540
672
  function getMemoizedU8Decoder() {
541
673
  if (!memoizedU8Decoder)
542
674
  memoizedU8Decoder = codecsNumbers.getU8Decoder();
543
675
  return memoizedU8Decoder;
544
676
  }
545
- function getMemoizedU8DecoderDescription(description) {
546
- const decoder = getMemoizedU8Decoder();
547
- return {
548
- ...decoder,
549
- description: description ?? decoder.description
550
- };
551
- }
552
- 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;
553
- 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;
554
- var numReadonlyNonSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable" : void 0;
555
- var messageHeaderDescription = __DEV__ ? "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses" : void 0;
556
677
  function getMessageHeaderEncoder() {
557
- return codecsDataStructures.getStructEncoder(
558
- [
559
- ["numSignerAccounts", getMemoizedU8EncoderDescription(numSignerAccountsDescription)],
560
- ["numReadonlySignerAccounts", getMemoizedU8EncoderDescription(numReadonlySignerAccountsDescription)],
561
- ["numReadonlyNonSignerAccounts", getMemoizedU8EncoderDescription(numReadonlyNonSignerAccountsDescription)]
562
- ],
563
- {
564
- description: messageHeaderDescription
565
- }
566
- );
678
+ return codecsDataStructures.getStructEncoder([
679
+ ["numSignerAccounts", getMemoizedU8Encoder()],
680
+ ["numReadonlySignerAccounts", getMemoizedU8Encoder()],
681
+ ["numReadonlyNonSignerAccounts", getMemoizedU8Encoder()]
682
+ ]);
567
683
  }
568
684
  function getMessageHeaderDecoder() {
569
- return codecsDataStructures.getStructDecoder(
570
- [
571
- ["numSignerAccounts", getMemoizedU8DecoderDescription(numSignerAccountsDescription)],
572
- ["numReadonlySignerAccounts", getMemoizedU8DecoderDescription(numReadonlySignerAccountsDescription)],
573
- ["numReadonlyNonSignerAccounts", getMemoizedU8DecoderDescription(numReadonlyNonSignerAccountsDescription)]
574
- ],
575
- {
576
- description: messageHeaderDescription
577
- }
578
- );
685
+ return codecsDataStructures.getStructDecoder([
686
+ ["numSignerAccounts", getMemoizedU8Decoder()],
687
+ ["numReadonlySignerAccounts", getMemoizedU8Decoder()],
688
+ ["numReadonlyNonSignerAccounts", getMemoizedU8Decoder()]
689
+ ]);
579
690
  }
580
- var programAddressIndexDescription = __DEV__ ? "The index of the program being called, according to the well-ordered accounts list for this transaction" : "programAddressIndex";
581
- var accountIndexDescription = __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : void 0;
582
- var accountIndicesDescription = __DEV__ ? "An optional list of account indices, according to the well-ordered accounts list for this transaction, in the order in which the program being called expects them" : "accountIndices";
583
- var dataDescription = __DEV__ ? "An optional buffer of data passed to the instruction" : "data";
584
691
  var memoizedGetInstructionEncoder;
585
692
  function getInstructionEncoder() {
586
693
  if (!memoizedGetInstructionEncoder) {
587
694
  memoizedGetInstructionEncoder = codecsCore.mapEncoder(
588
695
  codecsDataStructures.getStructEncoder([
589
- ["programAddressIndex", codecsNumbers.getU8Encoder({ description: programAddressIndexDescription })],
590
- [
591
- "accountIndices",
592
- codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder({ description: accountIndexDescription }), {
593
- description: accountIndicesDescription,
594
- size: codecsNumbers.getShortU16Encoder()
595
- })
596
- ],
597
- ["data", codecsDataStructures.getBytesEncoder({ description: dataDescription, size: codecsNumbers.getShortU16Encoder() })]
696
+ ["programAddressIndex", codecsNumbers.getU8Encoder()],
697
+ ["accountIndices", codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), { size: codecsNumbers.getShortU16Encoder() })],
698
+ ["data", codecsDataStructures.getBytesEncoder({ size: codecsNumbers.getShortU16Encoder() })]
598
699
  ]),
599
700
  // Convert an instruction to have all fields defined
600
701
  (instruction) => {
@@ -616,15 +717,9 @@ function getInstructionDecoder() {
616
717
  if (!memoizedGetInstructionDecoder) {
617
718
  memoizedGetInstructionDecoder = codecsCore.mapDecoder(
618
719
  codecsDataStructures.getStructDecoder([
619
- ["programAddressIndex", codecsNumbers.getU8Decoder({ description: programAddressIndexDescription })],
620
- [
621
- "accountIndices",
622
- codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder({ description: accountIndexDescription }), {
623
- description: accountIndicesDescription,
624
- size: codecsNumbers.getShortU16Decoder()
625
- })
626
- ],
627
- ["data", codecsDataStructures.getBytesDecoder({ description: dataDescription, size: codecsNumbers.getShortU16Decoder() })]
720
+ ["programAddressIndex", codecsNumbers.getU8Decoder()],
721
+ ["accountIndices", codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), { size: codecsNumbers.getShortU16Decoder() })],
722
+ ["data", codecsDataStructures.getBytesDecoder({ size: codecsNumbers.getShortU16Decoder() })]
628
723
  ]),
629
724
  // Convert an instruction to exclude optional fields if they are empty
630
725
  (instruction) => {
@@ -643,47 +738,38 @@ function getInstructionDecoder() {
643
738
  return memoizedGetInstructionDecoder;
644
739
  }
645
740
  var VERSION_FLAG_MASK = 128;
646
- var BASE_CONFIG = {
647
- description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
648
- fixedSize: null,
649
- maxSize: 1
650
- };
651
- function decode(bytes, offset = 0) {
652
- const firstByte = bytes[offset];
653
- if ((firstByte & VERSION_FLAG_MASK) === 0) {
654
- return ["legacy", offset];
655
- } else {
656
- const version = firstByte ^ VERSION_FLAG_MASK;
657
- return [version, offset + 1];
658
- }
659
- }
660
- function encode(value) {
661
- if (value === "legacy") {
662
- return new Uint8Array();
663
- }
664
- if (value < 0 || value > 127) {
665
- throw new Error(`Transaction version must be in the range [0, 127]. \`${value}\` given.`);
666
- }
667
- return new Uint8Array([value | VERSION_FLAG_MASK]);
741
+ function getTransactionVersionEncoder() {
742
+ return codecsCore.createEncoder({
743
+ getSizeFromValue: (value) => value === "legacy" ? 0 : 1,
744
+ maxSize: 1,
745
+ write: (value, bytes, offset) => {
746
+ if (value === "legacy") {
747
+ return offset;
748
+ }
749
+ if (value < 0 || value > 127) {
750
+ throw new Error(`Transaction version must be in the range [0, 127]. \`${value}\` given.`);
751
+ }
752
+ bytes.set([value | VERSION_FLAG_MASK], offset);
753
+ return offset + 1;
754
+ }
755
+ });
668
756
  }
669
757
  function getTransactionVersionDecoder() {
670
- return {
671
- ...BASE_CONFIG,
672
- decode
673
- };
674
- }
675
- function getTransactionVersionEncoder() {
676
- return {
677
- ...BASE_CONFIG,
678
- encode
679
- };
758
+ return codecsCore.createDecoder({
759
+ maxSize: 1,
760
+ read: (bytes, offset) => {
761
+ const firstByte = bytes[offset];
762
+ if ((firstByte & VERSION_FLAG_MASK) === 0) {
763
+ return ["legacy", offset];
764
+ } else {
765
+ const version = firstByte ^ VERSION_FLAG_MASK;
766
+ return [version, offset + 1];
767
+ }
768
+ }
769
+ });
680
770
  }
681
771
 
682
772
  // src/serializers/message.ts
683
- var staticAccountsDescription = __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "staticAccounts";
684
- var lifetimeTokenDescription = __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "lifetimeToken";
685
- var instructionsDescription = __DEV__ ? "A compact-array of instructions belonging to this transaction" : "instructions";
686
- var addressTableLookupsDescription = __DEV__ ? "A compact array of address table lookups belonging to this transaction" : "addressTableLookups";
687
773
  function getCompiledMessageLegacyEncoder() {
688
774
  return codecsDataStructures.getStructEncoder(getPreludeStructEncoderTuple());
689
775
  }
@@ -708,98 +794,52 @@ function getPreludeStructEncoderTuple() {
708
794
  return [
709
795
  ["version", getTransactionVersionEncoder()],
710
796
  ["header", getMessageHeaderEncoder()],
711
- [
712
- "staticAccounts",
713
- codecsDataStructures.getArrayEncoder(addresses.getAddressEncoder(), {
714
- description: staticAccountsDescription,
715
- size: codecsNumbers.getShortU16Encoder()
716
- })
717
- ],
718
- [
719
- "lifetimeToken",
720
- codecsStrings.getStringEncoder({
721
- description: lifetimeTokenDescription,
722
- encoding: codecsStrings.getBase58Encoder(),
723
- size: 32
724
- })
725
- ],
726
- [
727
- "instructions",
728
- codecsDataStructures.getArrayEncoder(getInstructionEncoder(), {
729
- description: instructionsDescription,
730
- size: codecsNumbers.getShortU16Encoder()
731
- })
732
- ]
797
+ ["staticAccounts", codecsDataStructures.getArrayEncoder(addresses.getAddressEncoder(), { size: codecsNumbers.getShortU16Encoder() })],
798
+ ["lifetimeToken", codecsStrings.getStringEncoder({ encoding: codecsStrings.getBase58Encoder(), size: 32 })],
799
+ ["instructions", codecsDataStructures.getArrayEncoder(getInstructionEncoder(), { size: codecsNumbers.getShortU16Encoder() })]
733
800
  ];
734
801
  }
735
802
  function getPreludeStructDecoderTuple() {
736
803
  return [
737
804
  ["version", getTransactionVersionDecoder()],
738
805
  ["header", getMessageHeaderDecoder()],
739
- [
740
- "staticAccounts",
741
- codecsDataStructures.getArrayDecoder(addresses.getAddressDecoder(), {
742
- description: staticAccountsDescription,
743
- size: codecsNumbers.getShortU16Decoder()
744
- })
745
- ],
746
- [
747
- "lifetimeToken",
748
- codecsStrings.getStringDecoder({
749
- description: lifetimeTokenDescription,
750
- encoding: codecsStrings.getBase58Decoder(),
751
- size: 32
752
- })
753
- ],
754
- [
755
- "instructions",
756
- codecsDataStructures.getArrayDecoder(getInstructionDecoder(), {
757
- description: instructionsDescription,
758
- size: codecsNumbers.getShortU16Decoder()
759
- })
760
- ],
806
+ ["staticAccounts", codecsDataStructures.getArrayDecoder(addresses.getAddressDecoder(), { size: codecsNumbers.getShortU16Decoder() })],
807
+ ["lifetimeToken", codecsStrings.getStringDecoder({ encoding: codecsStrings.getBase58Decoder(), size: 32 })],
808
+ ["instructions", codecsDataStructures.getArrayDecoder(getInstructionDecoder(), { size: codecsNumbers.getShortU16Decoder() })],
761
809
  ["addressTableLookups", getAddressTableLookupArrayDecoder()]
762
810
  ];
763
811
  }
764
812
  function getAddressTableLookupArrayEncoder() {
765
- return codecsDataStructures.getArrayEncoder(getAddressTableLookupEncoder(), {
766
- description: addressTableLookupsDescription,
767
- size: codecsNumbers.getShortU16Encoder()
768
- });
813
+ return codecsDataStructures.getArrayEncoder(getAddressTableLookupEncoder(), { size: codecsNumbers.getShortU16Encoder() });
769
814
  }
770
815
  function getAddressTableLookupArrayDecoder() {
771
- return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), {
772
- description: addressTableLookupsDescription,
773
- size: codecsNumbers.getShortU16Decoder()
774
- });
816
+ return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), { size: codecsNumbers.getShortU16Decoder() });
775
817
  }
776
- var messageDescription = __DEV__ ? "The wire format of a Solana transaction message" : "message";
777
818
  function getCompiledMessageEncoder() {
778
- return {
779
- description: messageDescription,
780
- encode: (compiledMessage) => {
819
+ return codecsCore.createEncoder({
820
+ getSizeFromValue: (compiledMessage) => {
781
821
  if (compiledMessage.version === "legacy") {
782
- return getCompiledMessageLegacyEncoder().encode(compiledMessage);
822
+ return getCompiledMessageLegacyEncoder().getSizeFromValue(compiledMessage);
783
823
  } else {
784
- return getCompiledMessageVersionedEncoder().encode(compiledMessage);
824
+ return getCompiledMessageVersionedEncoder().getSizeFromValue(compiledMessage);
785
825
  }
786
826
  },
787
- fixedSize: null,
788
- maxSize: null
789
- };
827
+ write: (compiledMessage, bytes, offset) => {
828
+ if (compiledMessage.version === "legacy") {
829
+ return getCompiledMessageLegacyEncoder().write(compiledMessage, bytes, offset);
830
+ } else {
831
+ return getCompiledMessageVersionedEncoder().write(compiledMessage, bytes, offset);
832
+ }
833
+ }
834
+ });
790
835
  }
791
836
  function getCompiledMessageDecoder() {
792
- return codecsCore.mapDecoder(
793
- codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple(), {
794
- description: messageDescription
795
- }),
796
- ({ addressTableLookups, ...restOfMessage }) => {
797
- if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
798
- return restOfMessage;
799
- }
800
- return { ...restOfMessage, addressTableLookups };
837
+ return codecsCore.mapDecoder(codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple()), ({ addressTableLookups, ...restOfMessage }) => {
838
+ if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
839
+ return restOfMessage;
801
840
  }
802
- );
841
+ return { ...restOfMessage, addressTableLookups };
842
+ });
803
843
  }
804
844
  function getCompiledMessageCodec() {
805
845
  return codecsCore.combineCodec(getCompiledMessageEncoder(), getCompiledMessageDecoder());
@@ -822,168 +862,36 @@ function getCompiledTransaction(transaction) {
822
862
  signatures
823
863
  };
824
864
  }
825
- function getAccountMetas(message) {
826
- const { header } = message;
827
- const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
828
- const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
829
- const accountMetas = [];
830
- let accountIndex = 0;
831
- for (let i = 0; i < numWritableSignerAccounts; i++) {
832
- accountMetas.push({
833
- address: message.staticAccounts[accountIndex],
834
- role: AccountRole.WRITABLE_SIGNER
835
- });
836
- accountIndex++;
837
- }
838
- for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
839
- accountMetas.push({
840
- address: message.staticAccounts[accountIndex],
841
- role: AccountRole.READONLY_SIGNER
842
- });
843
- accountIndex++;
844
- }
845
- for (let i = 0; i < numWritableNonSignerAccounts; i++) {
846
- accountMetas.push({
847
- address: message.staticAccounts[accountIndex],
848
- role: AccountRole.WRITABLE
849
- });
850
- accountIndex++;
851
- }
852
- for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
853
- accountMetas.push({
854
- address: message.staticAccounts[accountIndex],
855
- role: AccountRole.READONLY
856
- });
857
- accountIndex++;
858
- }
859
- return accountMetas;
860
- }
861
- function convertInstruction(instruction, accountMetas) {
862
- const programAddress = accountMetas[instruction.programAddressIndex]?.address;
863
- if (!programAddress) {
864
- throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
865
- }
866
- const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
867
- const { data } = instruction;
868
- return {
869
- programAddress,
870
- ...accounts && accounts.length ? { accounts } : {},
871
- ...data && data.length ? { data } : {}
872
- };
873
- }
874
- function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
875
- if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
876
- return {
877
- blockhash: messageLifetimeToken,
878
- lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
879
- // U64 MAX
880
- };
881
- } else {
882
- const nonceAccountAddress = firstInstruction.accounts[0].address;
883
- addresses.assertIsAddress(nonceAccountAddress);
884
- const nonceAuthorityAddress = firstInstruction.accounts[2].address;
885
- addresses.assertIsAddress(nonceAuthorityAddress);
886
- return {
887
- nonce: messageLifetimeToken,
888
- nonceAccountAddress,
889
- nonceAuthorityAddress
890
- };
891
- }
892
- }
893
- function convertSignatures(compiledTransaction) {
894
- const {
895
- compiledMessage: { staticAccounts },
896
- signatures
897
- } = compiledTransaction;
898
- return signatures.reduce((acc, sig, index) => {
899
- const allZeros = sig.every((byte) => byte === 0);
900
- if (allZeros)
901
- return acc;
902
- const address = staticAccounts[index];
903
- return { ...acc, [address]: sig };
904
- }, {});
905
- }
906
- function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
907
- const { compiledMessage } = compiledTransaction;
908
- if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
909
- throw new Error("Cannot convert transaction with addressTableLookups");
910
- }
911
- const feePayer = compiledMessage.staticAccounts[0];
912
- if (!feePayer)
913
- throw new Error("No fee payer set in CompiledTransaction");
914
- const accountMetas = getAccountMetas(compiledMessage);
915
- const instructions = compiledMessage.instructions.map(
916
- (compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
917
- );
918
- const firstInstruction = instructions[0];
919
- const lifetimeConstraint = getLifetimeConstraint(
920
- compiledMessage.lifetimeToken,
921
- firstInstruction,
922
- lastValidBlockHeight
923
- );
924
- const signatures = convertSignatures(compiledTransaction);
925
- return functional.pipe(
926
- createTransaction({ version: compiledMessage.version }),
927
- (tx) => setTransactionFeePayer(feePayer, tx),
928
- (tx) => instructions.reduce((acc, instruction) => {
929
- return appendTransactionInstruction(instruction, acc);
930
- }, tx),
931
- (tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
932
- (tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
933
- );
934
- }
935
865
 
936
866
  // src/serializers/transaction.ts
937
- var signaturesDescription = __DEV__ ? "A compact array of 64-byte, base-64 encoded Ed25519 signatures" : "signatures";
938
- var transactionDescription = __DEV__ ? "The wire format of a Solana transaction" : "transaction";
939
867
  function getCompiledTransactionEncoder() {
940
- return codecsDataStructures.getStructEncoder(
941
- [
942
- [
943
- "signatures",
944
- codecsDataStructures.getArrayEncoder(codecsDataStructures.getBytesEncoder({ size: 64 }), {
945
- description: signaturesDescription,
946
- size: codecsNumbers.getShortU16Encoder()
947
- })
948
- ],
949
- ["compiledMessage", getCompiledMessageEncoder()]
950
- ],
951
- {
952
- description: transactionDescription
953
- }
954
- );
955
- }
956
- function getSignatureDecoder() {
957
- return codecsCore.mapDecoder(codecsDataStructures.getBytesDecoder({ size: 64 }), (bytes) => bytes);
868
+ return codecsDataStructures.getStructEncoder([
869
+ ["signatures", codecsDataStructures.getArrayEncoder(codecsDataStructures.getBytesEncoder({ size: 64 }), { size: codecsNumbers.getShortU16Encoder() })],
870
+ ["compiledMessage", getCompiledMessageEncoder()]
871
+ ]);
958
872
  }
959
873
  function getCompiledTransactionDecoder() {
960
- return codecsDataStructures.getStructDecoder(
874
+ return codecsDataStructures.getStructDecoder([
961
875
  [
962
- [
963
- "signatures",
964
- codecsDataStructures.getArrayDecoder(getSignatureDecoder(), {
965
- description: signaturesDescription,
966
- size: codecsNumbers.getShortU16Decoder()
967
- })
968
- ],
969
- ["compiledMessage", getCompiledMessageDecoder()]
876
+ "signatures",
877
+ codecsDataStructures.getArrayDecoder(codecsDataStructures.getBytesDecoder({ size: 64 }), {
878
+ size: codecsNumbers.getShortU16Decoder()
879
+ })
970
880
  ],
971
- {
972
- description: transactionDescription
973
- }
974
- );
881
+ ["compiledMessage", getCompiledMessageDecoder()]
882
+ ]);
975
883
  }
976
884
  function getTransactionEncoder() {
977
885
  return codecsCore.mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
978
886
  }
979
- function getTransactionDecoder(lastValidBlockHeight) {
887
+ function getTransactionDecoder(config) {
980
888
  return codecsCore.mapDecoder(
981
889
  getCompiledTransactionDecoder(),
982
- (compiledTransaction) => decompileTransaction(compiledTransaction, lastValidBlockHeight)
890
+ (compiledTransaction) => decompileTransaction(compiledTransaction, config)
983
891
  );
984
892
  }
985
- function getTransactionCodec(lastValidBlockHeight) {
986
- return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
893
+ function getTransactionCodec(config) {
894
+ return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(config));
987
895
  }
988
896
  var base58Decoder;
989
897
  function getSignatureFromTransaction(transaction) {
@@ -991,11 +899,9 @@ function getSignatureFromTransaction(transaction) {
991
899
  base58Decoder = codecsStrings.getBase58Decoder();
992
900
  const signatureBytes = transaction.signatures[transaction.feePayer];
993
901
  if (!signatureBytes) {
994
- throw new Error(
995
- "Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
996
- );
902
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_SIGNATURE_NOT_COMPUTABLE);
997
903
  }
998
- const transactionSignature = base58Decoder.decode(signatureBytes)[0];
904
+ const transactionSignature = base58Decoder.decode(signatureBytes);
999
905
  return transactionSignature;
1000
906
  }
1001
907
  async function partiallySignTransaction(keyPairs, transaction) {
@@ -1026,34 +932,45 @@ async function signTransaction(keyPairs, transaction) {
1026
932
  function assertTransactionIsFullySigned(transaction) {
1027
933
  const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
1028
934
  const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
935
+ const missingSigs = [];
1029
936
  requiredSigners.forEach((address) => {
1030
937
  if (!transaction.signatures[address]) {
1031
- throw new Error(`Transaction is missing signature for address \`${address}\``);
938
+ missingSigs.push(address);
1032
939
  }
1033
940
  });
941
+ if (missingSigs.length > 0) {
942
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_MISSING_SIGNATURES, {
943
+ addresses: missingSigs
944
+ });
945
+ }
1034
946
  }
1035
947
  function getBase64EncodedWireTransaction(transaction) {
1036
948
  const wireTransactionBytes = getTransactionEncoder().encode(transaction);
1037
- return codecsStrings.getBase64Decoder().decode(wireTransactionBytes)[0];
949
+ return codecsStrings.getBase64Decoder().decode(wireTransactionBytes);
1038
950
  }
1039
951
 
1040
952
  exports.appendTransactionInstruction = appendTransactionInstruction;
1041
- exports.assertIsBlockhash = assertIsBlockhash;
953
+ exports.appendTransactionInstructions = appendTransactionInstructions;
1042
954
  exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
955
+ exports.assertIsTransactionWithBlockhashLifetime = assertIsTransactionWithBlockhashLifetime;
1043
956
  exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
1044
957
  exports.compileMessage = compileMessage;
1045
958
  exports.createTransaction = createTransaction;
959
+ exports.decompileTransaction = decompileTransaction;
1046
960
  exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
1047
961
  exports.getCompiledMessageCodec = getCompiledMessageCodec;
1048
962
  exports.getCompiledMessageDecoder = getCompiledMessageDecoder;
1049
963
  exports.getCompiledMessageEncoder = getCompiledMessageEncoder;
964
+ exports.getCompiledTransactionDecoder = getCompiledTransactionDecoder;
1050
965
  exports.getSignatureFromTransaction = getSignatureFromTransaction;
1051
966
  exports.getTransactionCodec = getTransactionCodec;
1052
967
  exports.getTransactionDecoder = getTransactionDecoder;
1053
968
  exports.getTransactionEncoder = getTransactionEncoder;
969
+ exports.getUnsignedTransaction = getUnsignedTransaction;
1054
970
  exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
1055
971
  exports.partiallySignTransaction = partiallySignTransaction;
1056
972
  exports.prependTransactionInstruction = prependTransactionInstruction;
973
+ exports.prependTransactionInstructions = prependTransactionInstructions;
1057
974
  exports.setTransactionFeePayer = setTransactionFeePayer;
1058
975
  exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
1059
976
  exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;