@solana/transactions 2.0.0-experimental.a7c51e0 → 2.0.0-experimental.a81a78e

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