@solana/transactions 2.0.0-experimental.e8095b1 → 2.0.0-experimental.e9e224b

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 (48) hide show
  1. package/README.md +314 -5
  2. package/dist/index.browser.cjs +354 -138
  3. package/dist/index.browser.cjs.map +1 -1
  4. package/dist/index.browser.js +357 -140
  5. package/dist/index.browser.js.map +1 -1
  6. package/dist/index.development.js +767 -1031
  7. package/dist/index.development.js.map +1 -1
  8. package/dist/index.native.js +355 -140
  9. package/dist/index.native.js.map +1 -1
  10. package/dist/index.node.cjs +354 -136
  11. package/dist/index.node.cjs.map +1 -1
  12. package/dist/index.node.js +357 -140
  13. package/dist/index.node.js.map +1 -1
  14. package/dist/index.production.min.js +20 -17
  15. package/dist/types/decompile-transaction.d.ts +7 -0
  16. package/dist/types/durable-nonce.d.ts +2 -3
  17. package/dist/types/serializers/message.d.ts +4 -4
  18. package/dist/types/serializers/transaction.d.ts +7 -4
  19. package/dist/types/signatures.d.ts +1 -0
  20. package/dist/types/wire-transaction.d.ts +1 -1
  21. package/package.json +12 -11
  22. package/dist/types/accounts.d.ts.map +0 -1
  23. package/dist/types/blockhash.d.ts.map +0 -1
  24. package/dist/types/compile-address-table-lookups.d.ts.map +0 -1
  25. package/dist/types/compile-header.d.ts.map +0 -1
  26. package/dist/types/compile-instructions.d.ts.map +0 -1
  27. package/dist/types/compile-lifetime-token.d.ts.map +0 -1
  28. package/dist/types/compile-static-accounts.d.ts.map +0 -1
  29. package/dist/types/compile-transaction.d.ts.map +0 -1
  30. package/dist/types/create-transaction.d.ts.map +0 -1
  31. package/dist/types/durable-nonce.d.ts.map +0 -1
  32. package/dist/types/fee-payer.d.ts.map +0 -1
  33. package/dist/types/index.d.ts.map +0 -1
  34. package/dist/types/instructions.d.ts.map +0 -1
  35. package/dist/types/message.d.ts.map +0 -1
  36. package/dist/types/serializers/address-table-lookup.d.ts.map +0 -1
  37. package/dist/types/serializers/header.d.ts.map +0 -1
  38. package/dist/types/serializers/index.d.ts.map +0 -1
  39. package/dist/types/serializers/instruction.d.ts.map +0 -1
  40. package/dist/types/serializers/message.d.ts.map +0 -1
  41. package/dist/types/serializers/transaction-version.d.ts.map +0 -1
  42. package/dist/types/serializers/transaction.d.ts.map +0 -1
  43. package/dist/types/serializers/unimplemented.d.ts +0 -3
  44. package/dist/types/serializers/unimplemented.d.ts.map +0 -1
  45. package/dist/types/signatures.d.ts.map +0 -1
  46. package/dist/types/types.d.ts.map +0 -1
  47. package/dist/types/unsigned-transaction.d.ts.map +0 -1
  48. package/dist/types/wire-transaction.d.ts.map +0 -1
@@ -1,10 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var umiSerializers = require('@metaplex-foundation/umi-serializers');
4
- var addresses = require('@solana/addresses');
3
+ var codecsStrings = require('@solana/codecs-strings');
5
4
  var codecsCore = require('@solana/codecs-core');
6
5
  var codecsDataStructures = require('@solana/codecs-data-structures');
7
6
  var codecsNumbers = require('@solana/codecs-numbers');
7
+ var addresses = require('@solana/addresses');
8
+ var functional = require('@solana/functional');
8
9
  var keys = require('@solana/keys');
9
10
 
10
11
  // ../build-scripts/env-shim.ts
@@ -25,7 +26,10 @@ function getUnsignedTransaction(transaction) {
25
26
  }
26
27
 
27
28
  // src/blockhash.ts
29
+ var base58Encoder;
28
30
  function assertIsBlockhash(putativeBlockhash) {
31
+ if (!base58Encoder)
32
+ base58Encoder = codecsStrings.getBase58Encoder();
29
33
  try {
30
34
  if (
31
35
  // Lowest value (32 bytes of zeroes)
@@ -34,8 +38,8 @@ function assertIsBlockhash(putativeBlockhash) {
34
38
  ) {
35
39
  throw new Error("Expected input string to decode to a byte array of length 32.");
36
40
  }
37
- const bytes2 = umiSerializers.base58.serialize(putativeBlockhash);
38
- const numBytes = bytes2.byteLength;
41
+ const bytes = base58Encoder.encode(putativeBlockhash);
42
+ const numBytes = bytes.byteLength;
39
43
  if (numBytes !== 32) {
40
44
  throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
41
45
  }
@@ -120,7 +124,7 @@ function isAdvanceNonceAccountInstruction(instruction) {
120
124
  instruction.accounts?.length === 3 && // First account is nonce account address
121
125
  instruction.accounts[0].address != null && instruction.accounts[0].role === AccountRole.WRITABLE && // Second account is recent blockhashes sysvar
122
126
  instruction.accounts[1].address === RECENT_BLOCKHASHES_SYSVAR_ADDRESS && instruction.accounts[1].role === AccountRole.READONLY && // Third account is nonce authority account
123
- instruction.accounts[2].address != null && instruction.accounts[2].role === AccountRole.READONLY_SIGNER;
127
+ instruction.accounts[2].address != null && isSignerRole(instruction.accounts[2].role);
124
128
  }
125
129
  function isAdvanceNonceAccountInstructionData(data) {
126
130
  return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;
@@ -128,21 +132,38 @@ function isAdvanceNonceAccountInstructionData(data) {
128
132
  function isDurableNonceTransaction(transaction) {
129
133
  return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
130
134
  }
135
+ function isAdvanceNonceAccountInstructionForNonce(instruction, nonceAccountAddress, nonceAuthorityAddress) {
136
+ return instruction.accounts[0].address === nonceAccountAddress && instruction.accounts[2].address === nonceAuthorityAddress;
137
+ }
131
138
  function setTransactionLifetimeUsingDurableNonce({
132
139
  nonce,
133
140
  nonceAccountAddress,
134
141
  nonceAuthorityAddress
135
142
  }, transaction) {
136
- const isAlreadyDurableNonceTransaction = isDurableNonceTransaction(transaction);
137
- if (isAlreadyDurableNonceTransaction && transaction.lifetimeConstraint.nonce === nonce && transaction.instructions[0].accounts[0].address === nonceAccountAddress && transaction.instructions[0].accounts[2].address === nonceAuthorityAddress) {
138
- return transaction;
143
+ let newInstructions;
144
+ const firstInstruction = transaction.instructions[0];
145
+ if (firstInstruction && isAdvanceNonceAccountInstruction(firstInstruction)) {
146
+ if (isAdvanceNonceAccountInstructionForNonce(firstInstruction, nonceAccountAddress, nonceAuthorityAddress)) {
147
+ if (isDurableNonceTransaction(transaction) && transaction.lifetimeConstraint.nonce === nonce) {
148
+ return transaction;
149
+ } else {
150
+ newInstructions = [firstInstruction, ...transaction.instructions.slice(1)];
151
+ }
152
+ } else {
153
+ newInstructions = [
154
+ createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
155
+ ...transaction.instructions.slice(1)
156
+ ];
157
+ }
158
+ } else {
159
+ newInstructions = [
160
+ createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
161
+ ...transaction.instructions
162
+ ];
139
163
  }
140
164
  const out = {
141
165
  ...getUnsignedTransaction(transaction),
142
- instructions: [
143
- createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
144
- ...isAlreadyDurableNonceTransaction ? transaction.instructions.slice(1) : transaction.instructions
145
- ],
166
+ instructions: newInstructions,
146
167
  lifetimeConstraint: {
147
168
  nonce
148
169
  }
@@ -465,6 +486,116 @@ function getCompiledTransaction(transaction) {
465
486
  signatures
466
487
  };
467
488
  }
489
+ function getAccountMetas(message) {
490
+ const { header } = message;
491
+ const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
492
+ const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
493
+ const accountMetas = [];
494
+ let accountIndex = 0;
495
+ for (let i = 0; i < numWritableSignerAccounts; i++) {
496
+ accountMetas.push({
497
+ address: message.staticAccounts[accountIndex],
498
+ role: AccountRole.WRITABLE_SIGNER
499
+ });
500
+ accountIndex++;
501
+ }
502
+ for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
503
+ accountMetas.push({
504
+ address: message.staticAccounts[accountIndex],
505
+ role: AccountRole.READONLY_SIGNER
506
+ });
507
+ accountIndex++;
508
+ }
509
+ for (let i = 0; i < numWritableNonSignerAccounts; i++) {
510
+ accountMetas.push({
511
+ address: message.staticAccounts[accountIndex],
512
+ role: AccountRole.WRITABLE
513
+ });
514
+ accountIndex++;
515
+ }
516
+ for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
517
+ accountMetas.push({
518
+ address: message.staticAccounts[accountIndex],
519
+ role: AccountRole.READONLY
520
+ });
521
+ accountIndex++;
522
+ }
523
+ return accountMetas;
524
+ }
525
+ function convertInstruction(instruction, accountMetas) {
526
+ const programAddress = accountMetas[instruction.programAddressIndex]?.address;
527
+ if (!programAddress) {
528
+ throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
529
+ }
530
+ const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
531
+ const { data } = instruction;
532
+ return {
533
+ programAddress,
534
+ ...accounts && accounts.length ? { accounts } : {},
535
+ ...data && data.length ? { data } : {}
536
+ };
537
+ }
538
+ function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
539
+ if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
540
+ return {
541
+ blockhash: messageLifetimeToken,
542
+ lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
543
+ // U64 MAX
544
+ };
545
+ } else {
546
+ const nonceAccountAddress = firstInstruction.accounts[0].address;
547
+ addresses.assertIsAddress(nonceAccountAddress);
548
+ const nonceAuthorityAddress = firstInstruction.accounts[2].address;
549
+ addresses.assertIsAddress(nonceAuthorityAddress);
550
+ return {
551
+ nonce: messageLifetimeToken,
552
+ nonceAccountAddress,
553
+ nonceAuthorityAddress
554
+ };
555
+ }
556
+ }
557
+ function convertSignatures(compiledTransaction) {
558
+ const {
559
+ compiledMessage: { staticAccounts },
560
+ signatures
561
+ } = compiledTransaction;
562
+ return signatures.reduce((acc, sig, index) => {
563
+ const allZeros = sig.every((byte) => byte === 0);
564
+ if (allZeros)
565
+ return acc;
566
+ const address = staticAccounts[index];
567
+ return { ...acc, [address]: sig };
568
+ }, {});
569
+ }
570
+ function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
571
+ const { compiledMessage } = compiledTransaction;
572
+ if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
573
+ throw new Error("Cannot convert transaction with addressTableLookups");
574
+ }
575
+ const feePayer = compiledMessage.staticAccounts[0];
576
+ if (!feePayer)
577
+ throw new Error("No fee payer set in CompiledTransaction");
578
+ const accountMetas = getAccountMetas(compiledMessage);
579
+ const instructions = compiledMessage.instructions.map(
580
+ (compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
581
+ );
582
+ const firstInstruction = instructions[0];
583
+ const lifetimeConstraint = getLifetimeConstraint(
584
+ compiledMessage.lifetimeToken,
585
+ firstInstruction,
586
+ lastValidBlockHeight
587
+ );
588
+ const signatures = convertSignatures(compiledTransaction);
589
+ return functional.pipe(
590
+ createTransaction({ version: compiledMessage.version }),
591
+ (tx) => setTransactionFeePayer(feePayer, tx),
592
+ (tx) => instructions.reduce((acc, instruction) => {
593
+ return appendTransactionInstruction(instruction, acc);
594
+ }, tx),
595
+ (tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
596
+ (tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
597
+ );
598
+ }
468
599
  var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
469
600
  var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
470
601
  var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
@@ -521,32 +652,54 @@ function getAddressTableLookupDecoder() {
521
652
  }
522
653
  return memoizedAddressTableLookupDecoder;
523
654
  }
524
- function getAddressTableLookupCodec() {
525
- return codecsCore.combineCodec(getAddressTableLookupEncoder(), getAddressTableLookupDecoder());
655
+ var memoizedU8Encoder;
656
+ function getMemoizedU8Encoder() {
657
+ if (!memoizedU8Encoder)
658
+ memoizedU8Encoder = codecsNumbers.getU8Encoder();
659
+ return memoizedU8Encoder;
526
660
  }
527
- var memoizedU8Codec;
528
- function getMemoizedU8Codec() {
529
- if (!memoizedU8Codec)
530
- memoizedU8Codec = codecsNumbers.getU8Codec();
531
- return memoizedU8Codec;
661
+ function getMemoizedU8EncoderDescription(description) {
662
+ const encoder = getMemoizedU8Encoder();
663
+ return {
664
+ ...encoder,
665
+ description: description ?? encoder.description
666
+ };
532
667
  }
533
- function getMemoizedU8CodecDescription(description) {
534
- const codec = getMemoizedU8Codec();
668
+ var memoizedU8Decoder;
669
+ function getMemoizedU8Decoder() {
670
+ if (!memoizedU8Decoder)
671
+ memoizedU8Decoder = codecsNumbers.getU8Decoder();
672
+ return memoizedU8Decoder;
673
+ }
674
+ function getMemoizedU8DecoderDescription(description) {
675
+ const decoder = getMemoizedU8Decoder();
535
676
  return {
536
- ...codec,
537
- description: description ?? codec.description
677
+ ...decoder,
678
+ description: description ?? decoder.description
538
679
  };
539
680
  }
540
681
  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;
541
682
  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;
542
683
  var numReadonlyNonSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable" : void 0;
543
684
  var messageHeaderDescription = __DEV__ ? "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses" : void 0;
544
- function getMessageHeaderCodec() {
545
- return codecsDataStructures.getStructCodec(
685
+ function getMessageHeaderEncoder() {
686
+ return codecsDataStructures.getStructEncoder(
546
687
  [
547
- ["numSignerAccounts", getMemoizedU8CodecDescription(numSignerAccountsDescription)],
548
- ["numReadonlySignerAccounts", getMemoizedU8CodecDescription(numReadonlySignerAccountsDescription)],
549
- ["numReadonlyNonSignerAccounts", getMemoizedU8CodecDescription(numReadonlyNonSignerAccountsDescription)]
688
+ ["numSignerAccounts", getMemoizedU8EncoderDescription(numSignerAccountsDescription)],
689
+ ["numReadonlySignerAccounts", getMemoizedU8EncoderDescription(numReadonlySignerAccountsDescription)],
690
+ ["numReadonlyNonSignerAccounts", getMemoizedU8EncoderDescription(numReadonlyNonSignerAccountsDescription)]
691
+ ],
692
+ {
693
+ description: messageHeaderDescription
694
+ }
695
+ );
696
+ }
697
+ function getMessageHeaderDecoder() {
698
+ return codecsDataStructures.getStructDecoder(
699
+ [
700
+ ["numSignerAccounts", getMemoizedU8DecoderDescription(numSignerAccountsDescription)],
701
+ ["numReadonlySignerAccounts", getMemoizedU8DecoderDescription(numReadonlySignerAccountsDescription)],
702
+ ["numReadonlyNonSignerAccounts", getMemoizedU8DecoderDescription(numReadonlyNonSignerAccountsDescription)]
550
703
  ],
551
704
  {
552
705
  description: messageHeaderDescription
@@ -618,17 +771,14 @@ function getInstructionDecoder() {
618
771
  }
619
772
  return memoizedGetInstructionDecoder;
620
773
  }
621
- function getInstructionCodec() {
622
- return codecsCore.combineCodec(getInstructionEncoder(), getInstructionDecoder());
623
- }
624
774
  var VERSION_FLAG_MASK = 128;
625
775
  var BASE_CONFIG = {
626
776
  description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
627
777
  fixedSize: null,
628
778
  maxSize: 1
629
779
  };
630
- function decode(bytes2, offset = 0) {
631
- const firstByte = bytes2[offset];
780
+ function decode(bytes, offset = 0) {
781
+ const firstByte = bytes[offset];
632
782
  if ((firstByte & VERSION_FLAG_MASK) === 0) {
633
783
  return ["legacy", offset];
634
784
  } else {
@@ -657,128 +807,187 @@ function getTransactionVersionEncoder() {
657
807
  encode
658
808
  };
659
809
  }
660
- function getTransactionVersionCodec() {
661
- return codecsCore.combineCodec(getTransactionVersionEncoder(), getTransactionVersionDecoder());
662
- }
663
-
664
- // src/serializers/unimplemented.ts
665
- function getError(type, name) {
666
- const functionSuffix = name + type[0].toUpperCase() + type.slice(1);
667
- return new Error(
668
- `No ${type} exists for ${name}. Use \`get${functionSuffix}()\` if you need a ${type}, and \`get${name}Codec()\` if you need to both encode and decode ${name}`
669
- );
670
- }
671
- function getUnimplementedDecoder(name) {
672
- return () => {
673
- throw getError("decoder", name);
674
- };
675
- }
676
810
 
677
811
  // src/serializers/message.ts
678
- var BASE_CONFIG2 = {
679
- description: __DEV__ ? "The wire format of a Solana transaction message" : "",
680
- fixedSize: null,
681
- maxSize: null
682
- };
683
- function serialize(compiledMessage) {
684
- if (compiledMessage.version === "legacy") {
685
- return umiSerializers.struct(getPreludeStructSerializerTuple()).serialize(compiledMessage);
686
- } else {
687
- return umiSerializers.mapSerializer(
688
- umiSerializers.struct([
689
- ...getPreludeStructSerializerTuple(),
690
- ["addressTableLookups", getAddressTableLookupsSerializer()]
691
- ]),
692
- (value) => {
693
- if (value.version === "legacy") {
694
- return value;
695
- }
696
- return {
697
- ...value,
698
- addressTableLookups: value.addressTableLookups ?? []
699
- };
700
- }
701
- ).serialize(compiledMessage);
702
- }
812
+ var staticAccountsDescription = __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "staticAccounts";
813
+ var lifetimeTokenDescription = __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "lifetimeToken";
814
+ var instructionsDescription = __DEV__ ? "A compact-array of instructions belonging to this transaction" : "instructions";
815
+ var addressTableLookupsDescription = __DEV__ ? "A compact array of address table lookups belonging to this transaction" : "addressTableLookups";
816
+ function getCompiledMessageLegacyEncoder() {
817
+ return codecsDataStructures.getStructEncoder(getPreludeStructEncoderTuple());
703
818
  }
704
- function toSerializer(codec) {
705
- return {
706
- description: codec.description,
707
- deserialize: codec.decode,
708
- fixedSize: codec.fixedSize,
709
- maxSize: codec.maxSize,
710
- serialize: codec.encode
711
- };
819
+ function getCompiledMessageVersionedEncoder() {
820
+ return codecsCore.mapEncoder(
821
+ codecsDataStructures.getStructEncoder([
822
+ ...getPreludeStructEncoderTuple(),
823
+ ["addressTableLookups", getAddressTableLookupArrayEncoder()]
824
+ ]),
825
+ (value) => {
826
+ if (value.version === "legacy") {
827
+ return value;
828
+ }
829
+ return {
830
+ ...value,
831
+ addressTableLookups: value.addressTableLookups ?? []
832
+ };
833
+ }
834
+ );
712
835
  }
713
- function getPreludeStructSerializerTuple() {
836
+ function getPreludeStructEncoderTuple() {
714
837
  return [
715
- ["version", toSerializer(getTransactionVersionCodec())],
716
- ["header", toSerializer(getMessageHeaderCodec())],
838
+ ["version", getTransactionVersionEncoder()],
839
+ ["header", getMessageHeaderEncoder()],
717
840
  [
718
841
  "staticAccounts",
719
- umiSerializers.array(toSerializer(addresses.getAddressCodec()), {
720
- description: __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "",
721
- size: umiSerializers.shortU16()
842
+ codecsDataStructures.getArrayEncoder(addresses.getAddressEncoder(), {
843
+ description: staticAccountsDescription,
844
+ size: codecsNumbers.getShortU16Encoder()
722
845
  })
723
846
  ],
724
847
  [
725
848
  "lifetimeToken",
726
- umiSerializers.string({
727
- description: __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "",
728
- encoding: umiSerializers.base58,
849
+ codecsStrings.getStringEncoder({
850
+ description: lifetimeTokenDescription,
851
+ encoding: codecsStrings.getBase58Encoder(),
729
852
  size: 32
730
853
  })
731
854
  ],
732
855
  [
733
856
  "instructions",
734
- umiSerializers.array(toSerializer(getInstructionCodec()), {
735
- description: __DEV__ ? "A compact-array of instructions belonging to this transaction" : "",
736
- size: umiSerializers.shortU16()
857
+ codecsDataStructures.getArrayEncoder(getInstructionEncoder(), {
858
+ description: instructionsDescription,
859
+ size: codecsNumbers.getShortU16Encoder()
737
860
  })
738
861
  ]
739
862
  ];
740
863
  }
741
- function getAddressTableLookupsSerializer() {
742
- return umiSerializers.array(toSerializer(getAddressTableLookupCodec()), {
743
- ...__DEV__ ? { description: "A compact array of address table lookups belonging to this transaction" } : null,
744
- size: umiSerializers.shortU16()
864
+ function getPreludeStructDecoderTuple() {
865
+ return [
866
+ ["version", getTransactionVersionDecoder()],
867
+ ["header", getMessageHeaderDecoder()],
868
+ [
869
+ "staticAccounts",
870
+ codecsDataStructures.getArrayDecoder(addresses.getAddressDecoder(), {
871
+ description: staticAccountsDescription,
872
+ size: codecsNumbers.getShortU16Decoder()
873
+ })
874
+ ],
875
+ [
876
+ "lifetimeToken",
877
+ codecsStrings.getStringDecoder({
878
+ description: lifetimeTokenDescription,
879
+ encoding: codecsStrings.getBase58Decoder(),
880
+ size: 32
881
+ })
882
+ ],
883
+ [
884
+ "instructions",
885
+ codecsDataStructures.getArrayDecoder(getInstructionDecoder(), {
886
+ description: instructionsDescription,
887
+ size: codecsNumbers.getShortU16Decoder()
888
+ })
889
+ ],
890
+ ["addressTableLookups", getAddressTableLookupArrayDecoder()]
891
+ ];
892
+ }
893
+ function getAddressTableLookupArrayEncoder() {
894
+ return codecsDataStructures.getArrayEncoder(getAddressTableLookupEncoder(), {
895
+ description: addressTableLookupsDescription,
896
+ size: codecsNumbers.getShortU16Encoder()
745
897
  });
746
898
  }
899
+ function getAddressTableLookupArrayDecoder() {
900
+ return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), {
901
+ description: addressTableLookupsDescription,
902
+ size: codecsNumbers.getShortU16Decoder()
903
+ });
904
+ }
905
+ var messageDescription = __DEV__ ? "The wire format of a Solana transaction message" : "message";
747
906
  function getCompiledMessageEncoder() {
748
907
  return {
749
- ...BASE_CONFIG2,
750
- deserialize: getUnimplementedDecoder("CompiledMessage"),
751
- serialize
908
+ description: messageDescription,
909
+ encode: (compiledMessage) => {
910
+ if (compiledMessage.version === "legacy") {
911
+ return getCompiledMessageLegacyEncoder().encode(compiledMessage);
912
+ } else {
913
+ return getCompiledMessageVersionedEncoder().encode(compiledMessage);
914
+ }
915
+ },
916
+ fixedSize: null,
917
+ maxSize: null
752
918
  };
753
919
  }
920
+ function getCompiledMessageDecoder() {
921
+ return codecsCore.mapDecoder(
922
+ codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple(), {
923
+ description: messageDescription
924
+ }),
925
+ ({ addressTableLookups, ...restOfMessage }) => {
926
+ if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
927
+ return restOfMessage;
928
+ }
929
+ return { ...restOfMessage, addressTableLookups };
930
+ }
931
+ );
932
+ }
754
933
 
755
934
  // src/serializers/transaction.ts
756
- var BASE_CONFIG3 = {
757
- description: __DEV__ ? "The wire format of a Solana transaction" : "",
758
- fixedSize: null,
759
- maxSize: null
760
- };
761
- function serialize2(transaction) {
762
- const compiledTransaction = getCompiledTransaction(transaction);
763
- return umiSerializers.struct([
935
+ var signaturesDescription = __DEV__ ? "A compact array of 64-byte, base-64 encoded Ed25519 signatures" : "signatures";
936
+ var transactionDescription = __DEV__ ? "The wire format of a Solana transaction" : "transaction";
937
+ function getCompiledTransactionEncoder() {
938
+ return codecsDataStructures.getStructEncoder(
764
939
  [
765
- "signatures",
766
- umiSerializers.array(umiSerializers.bytes({ size: 64 }), {
767
- ...__DEV__ ? { description: "A compact array of 64-byte, base-64 encoded Ed25519 signatures" } : null,
768
- size: umiSerializers.shortU16()
769
- })
940
+ [
941
+ "signatures",
942
+ codecsDataStructures.getArrayEncoder(codecsDataStructures.getBytesEncoder({ size: 64 }), {
943
+ description: signaturesDescription,
944
+ size: codecsNumbers.getShortU16Encoder()
945
+ })
946
+ ],
947
+ ["compiledMessage", getCompiledMessageEncoder()]
770
948
  ],
771
- ["compiledMessage", getCompiledMessageEncoder()]
772
- ]).serialize(compiledTransaction);
949
+ {
950
+ description: transactionDescription
951
+ }
952
+ );
953
+ }
954
+ function getSignatureDecoder() {
955
+ return codecsCore.mapDecoder(codecsDataStructures.getBytesDecoder({ size: 64 }), (bytes) => bytes);
956
+ }
957
+ function getCompiledTransactionDecoder() {
958
+ return codecsDataStructures.getStructDecoder(
959
+ [
960
+ [
961
+ "signatures",
962
+ codecsDataStructures.getArrayDecoder(getSignatureDecoder(), {
963
+ description: signaturesDescription,
964
+ size: codecsNumbers.getShortU16Decoder()
965
+ })
966
+ ],
967
+ ["compiledMessage", getCompiledMessageDecoder()]
968
+ ],
969
+ {
970
+ description: transactionDescription
971
+ }
972
+ );
773
973
  }
774
974
  function getTransactionEncoder() {
775
- return {
776
- ...BASE_CONFIG3,
777
- deserialize: getUnimplementedDecoder("CompiledMessage"),
778
- serialize: serialize2
779
- };
975
+ return codecsCore.mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
780
976
  }
977
+ function getTransactionDecoder(lastValidBlockHeight) {
978
+ return codecsCore.mapDecoder(
979
+ getCompiledTransactionDecoder(),
980
+ (compiledTransaction) => decompileTransaction(compiledTransaction, lastValidBlockHeight)
981
+ );
982
+ }
983
+ function getTransactionCodec(lastValidBlockHeight) {
984
+ return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
985
+ }
986
+ var base58Encoder2;
987
+ var base58Decoder;
781
988
  function assertIsTransactionSignature(putativeTransactionSignature) {
989
+ if (!base58Encoder2)
990
+ base58Encoder2 = codecsStrings.getBase58Encoder();
782
991
  try {
783
992
  if (
784
993
  // Lowest value (64 bytes of zeroes)
@@ -787,8 +996,8 @@ function assertIsTransactionSignature(putativeTransactionSignature) {
787
996
  ) {
788
997
  throw new Error("Expected input string to decode to a byte array of length 64.");
789
998
  }
790
- const bytes2 = umiSerializers.base58.serialize(putativeTransactionSignature);
791
- const numBytes = bytes2.byteLength;
999
+ const bytes = base58Encoder2.encode(putativeTransactionSignature);
1000
+ const numBytes = bytes.byteLength;
792
1001
  if (numBytes !== 64) {
793
1002
  throw new Error(`Expected input string to decode to a byte array of length 64. Actual length: ${numBytes}`);
794
1003
  }
@@ -799,6 +1008,8 @@ function assertIsTransactionSignature(putativeTransactionSignature) {
799
1008
  }
800
1009
  }
801
1010
  function isTransactionSignature(putativeTransactionSignature) {
1011
+ if (!base58Encoder2)
1012
+ base58Encoder2 = codecsStrings.getBase58Encoder();
802
1013
  if (
803
1014
  // Lowest value (64 bytes of zeroes)
804
1015
  putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
@@ -806,37 +1017,32 @@ function isTransactionSignature(putativeTransactionSignature) {
806
1017
  ) {
807
1018
  return false;
808
1019
  }
809
- const bytes2 = umiSerializers.base58.serialize(putativeTransactionSignature);
810
- const numBytes = bytes2.byteLength;
1020
+ const bytes = base58Encoder2.encode(putativeTransactionSignature);
1021
+ const numBytes = bytes.byteLength;
811
1022
  if (numBytes !== 64) {
812
1023
  return false;
813
1024
  }
814
1025
  return true;
815
1026
  }
816
- async function getCompiledMessageSignature(message, secretKey) {
817
- const wireMessageBytes = getCompiledMessageEncoder().serialize(message);
818
- const signature = await keys.signBytes(secretKey, wireMessageBytes);
819
- return signature;
820
- }
821
1027
  function getSignatureFromTransaction(transaction) {
1028
+ if (!base58Decoder)
1029
+ base58Decoder = codecsStrings.getBase58Decoder();
822
1030
  const signatureBytes = transaction.signatures[transaction.feePayer];
823
1031
  if (!signatureBytes) {
824
1032
  throw new Error(
825
1033
  "Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
826
1034
  );
827
1035
  }
828
- const transactionSignature2 = umiSerializers.base58.deserialize(signatureBytes)[0];
1036
+ const transactionSignature2 = base58Decoder.decode(signatureBytes)[0];
829
1037
  return transactionSignature2;
830
1038
  }
831
1039
  async function signTransaction(keyPairs, transaction) {
832
1040
  const compiledMessage = compileMessage(transaction);
833
1041
  const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
1042
+ const wireMessageBytes = getCompiledMessageEncoder().encode(compiledMessage);
834
1043
  const publicKeySignaturePairs = await Promise.all(
835
1044
  keyPairs.map(
836
- (keyPair) => Promise.all([
837
- addresses.getAddressFromPublicKey(keyPair.publicKey),
838
- getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
839
- ])
1045
+ (keyPair) => Promise.all([addresses.getAddressFromPublicKey(keyPair.publicKey), keys.signBytes(keyPair.privateKey, wireMessageBytes)])
840
1046
  )
841
1047
  );
842
1048
  for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
@@ -853,10 +1059,19 @@ function transactionSignature(putativeTransactionSignature) {
853
1059
  assertIsTransactionSignature(putativeTransactionSignature);
854
1060
  return putativeTransactionSignature;
855
1061
  }
1062
+ function assertTransactionIsFullySigned(transaction) {
1063
+ const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
1064
+ const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
1065
+ requiredSigners.forEach((address) => {
1066
+ if (!transaction.signatures[address]) {
1067
+ throw new Error(`Transaction is missing signature for address \`${address}\``);
1068
+ }
1069
+ });
1070
+ }
856
1071
 
857
1072
  // src/wire-transaction.ts
858
1073
  function getBase64EncodedWireTransaction(transaction) {
859
- const wireTransactionBytes = getTransactionEncoder().serialize(transaction);
1074
+ const wireTransactionBytes = getTransactionEncoder().encode(transaction);
860
1075
  {
861
1076
  return btoa(String.fromCharCode(...wireTransactionBytes));
862
1077
  }
@@ -866,9 +1081,12 @@ exports.appendTransactionInstruction = appendTransactionInstruction;
866
1081
  exports.assertIsBlockhash = assertIsBlockhash;
867
1082
  exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
868
1083
  exports.assertIsTransactionSignature = assertIsTransactionSignature;
1084
+ exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
869
1085
  exports.createTransaction = createTransaction;
870
1086
  exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
871
1087
  exports.getSignatureFromTransaction = getSignatureFromTransaction;
1088
+ exports.getTransactionCodec = getTransactionCodec;
1089
+ exports.getTransactionDecoder = getTransactionDecoder;
872
1090
  exports.getTransactionEncoder = getTransactionEncoder;
873
1091
  exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
874
1092
  exports.isTransactionSignature = isTransactionSignature;
@@ -878,5 +1096,3 @@ exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockh
878
1096
  exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
879
1097
  exports.signTransaction = signTransaction;
880
1098
  exports.transactionSignature = transactionSignature;
881
- //# sourceMappingURL=out.js.map
882
- //# sourceMappingURL=index.browser.cjs.map