@solana/transactions 2.0.0-experimental.68e85dc → 2.0.0-experimental.6910664

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 (44) hide show
  1. package/dist/index.browser.cjs +323 -11
  2. package/dist/index.browser.cjs.map +1 -1
  3. package/dist/index.browser.js +326 -15
  4. package/dist/index.browser.js.map +1 -1
  5. package/dist/index.development.js +479 -9
  6. package/dist/index.development.js.map +1 -1
  7. package/dist/index.native.js +326 -17
  8. package/dist/index.native.js.map +1 -1
  9. package/dist/index.node.cjs +323 -9
  10. package/dist/index.node.cjs.map +1 -1
  11. package/dist/index.node.js +328 -15
  12. package/dist/index.node.js.map +1 -1
  13. package/dist/index.production.min.js +20 -17
  14. package/dist/types/accounts.d.ts.map +1 -0
  15. package/dist/types/blockhash.d.ts.map +1 -0
  16. package/dist/types/compile-address-table-lookups.d.ts.map +1 -0
  17. package/dist/types/compile-header.d.ts.map +1 -0
  18. package/dist/types/compile-instructions.d.ts.map +1 -0
  19. package/dist/types/compile-lifetime-token.d.ts.map +1 -0
  20. package/dist/types/compile-static-accounts.d.ts.map +1 -0
  21. package/dist/types/compile-transaction.d.ts.map +1 -0
  22. package/dist/types/create-transaction.d.ts.map +1 -0
  23. package/dist/types/decompile-transaction.d.ts +7 -0
  24. package/dist/types/decompile-transaction.d.ts.map +1 -0
  25. package/dist/types/durable-nonce.d.ts +2 -3
  26. package/dist/types/durable-nonce.d.ts.map +1 -0
  27. package/dist/types/fee-payer.d.ts.map +1 -0
  28. package/dist/types/index.d.ts.map +1 -0
  29. package/dist/types/instructions.d.ts.map +1 -0
  30. package/dist/types/message.d.ts.map +1 -0
  31. package/dist/types/serializers/address-table-lookup.d.ts.map +1 -0
  32. package/dist/types/serializers/header.d.ts.map +1 -0
  33. package/dist/types/serializers/index.d.ts.map +1 -0
  34. package/dist/types/serializers/instruction.d.ts.map +1 -0
  35. package/dist/types/serializers/message.d.ts.map +1 -0
  36. package/dist/types/serializers/transaction-version.d.ts.map +1 -0
  37. package/dist/types/serializers/transaction.d.ts +4 -2
  38. package/dist/types/serializers/transaction.d.ts.map +1 -0
  39. package/dist/types/signatures.d.ts +1 -0
  40. package/dist/types/signatures.d.ts.map +1 -0
  41. package/dist/types/types.d.ts.map +1 -0
  42. package/dist/types/unsigned-transaction.d.ts.map +1 -0
  43. package/dist/types/wire-transaction.d.ts.map +1 -0
  44. package/package.json +9 -9
@@ -5,6 +5,7 @@ var codecsCore = require('@solana/codecs-core');
5
5
  var codecsDataStructures = require('@solana/codecs-data-structures');
6
6
  var codecsNumbers = require('@solana/codecs-numbers');
7
7
  var addresses = require('@solana/addresses');
8
+ var functional = require('@solana/functional');
8
9
  var codecsStrings = require('@solana/codecs-strings');
9
10
  var keys = require('@solana/keys');
10
11
 
@@ -121,7 +122,7 @@ function isAdvanceNonceAccountInstruction(instruction) {
121
122
  instruction.accounts?.length === 3 && // First account is nonce account address
122
123
  instruction.accounts[0].address != null && instruction.accounts[0].role === AccountRole.WRITABLE && // Second account is recent blockhashes sysvar
123
124
  instruction.accounts[1].address === RECENT_BLOCKHASHES_SYSVAR_ADDRESS && instruction.accounts[1].role === AccountRole.READONLY && // Third account is nonce authority account
124
- instruction.accounts[2].address != null && instruction.accounts[2].role === AccountRole.READONLY_SIGNER;
125
+ instruction.accounts[2].address != null && isSignerRole(instruction.accounts[2].role);
125
126
  }
126
127
  function isAdvanceNonceAccountInstructionData(data) {
127
128
  return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;
@@ -129,21 +130,38 @@ function isAdvanceNonceAccountInstructionData(data) {
129
130
  function isDurableNonceTransaction(transaction) {
130
131
  return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
131
132
  }
133
+ function isAdvanceNonceAccountInstructionForNonce(instruction, nonceAccountAddress, nonceAuthorityAddress) {
134
+ return instruction.accounts[0].address === nonceAccountAddress && instruction.accounts[2].address === nonceAuthorityAddress;
135
+ }
132
136
  function setTransactionLifetimeUsingDurableNonce({
133
137
  nonce,
134
138
  nonceAccountAddress,
135
139
  nonceAuthorityAddress
136
140
  }, transaction) {
137
- const isAlreadyDurableNonceTransaction = isDurableNonceTransaction(transaction);
138
- if (isAlreadyDurableNonceTransaction && transaction.lifetimeConstraint.nonce === nonce && transaction.instructions[0].accounts[0].address === nonceAccountAddress && transaction.instructions[0].accounts[2].address === nonceAuthorityAddress) {
139
- return transaction;
141
+ let newInstructions;
142
+ const firstInstruction = transaction.instructions[0];
143
+ if (firstInstruction && isAdvanceNonceAccountInstruction(firstInstruction)) {
144
+ if (isAdvanceNonceAccountInstructionForNonce(firstInstruction, nonceAccountAddress, nonceAuthorityAddress)) {
145
+ if (isDurableNonceTransaction(transaction) && transaction.lifetimeConstraint.nonce === nonce) {
146
+ return transaction;
147
+ } else {
148
+ newInstructions = [firstInstruction, ...transaction.instructions.slice(1)];
149
+ }
150
+ } else {
151
+ newInstructions = [
152
+ createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
153
+ ...transaction.instructions.slice(1)
154
+ ];
155
+ }
156
+ } else {
157
+ newInstructions = [
158
+ createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
159
+ ...transaction.instructions
160
+ ];
140
161
  }
141
162
  const out = {
142
163
  ...getUnsignedTransaction(transaction),
143
- instructions: [
144
- createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
145
- ...isAlreadyDurableNonceTransaction ? transaction.instructions.slice(1) : transaction.instructions
146
- ],
164
+ instructions: newInstructions,
147
165
  lifetimeConstraint: {
148
166
  nonce
149
167
  }
@@ -466,6 +484,116 @@ function getCompiledTransaction(transaction) {
466
484
  signatures
467
485
  };
468
486
  }
487
+ function getAccountMetas(message) {
488
+ const { header } = message;
489
+ const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
490
+ const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
491
+ const accountMetas = [];
492
+ let accountIndex = 0;
493
+ for (let i = 0; i < numWritableSignerAccounts; i++) {
494
+ accountMetas.push({
495
+ address: message.staticAccounts[accountIndex],
496
+ role: AccountRole.WRITABLE_SIGNER
497
+ });
498
+ accountIndex++;
499
+ }
500
+ for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
501
+ accountMetas.push({
502
+ address: message.staticAccounts[accountIndex],
503
+ role: AccountRole.READONLY_SIGNER
504
+ });
505
+ accountIndex++;
506
+ }
507
+ for (let i = 0; i < numWritableNonSignerAccounts; i++) {
508
+ accountMetas.push({
509
+ address: message.staticAccounts[accountIndex],
510
+ role: AccountRole.WRITABLE
511
+ });
512
+ accountIndex++;
513
+ }
514
+ for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
515
+ accountMetas.push({
516
+ address: message.staticAccounts[accountIndex],
517
+ role: AccountRole.READONLY
518
+ });
519
+ accountIndex++;
520
+ }
521
+ return accountMetas;
522
+ }
523
+ function convertInstruction(instruction, accountMetas) {
524
+ const programAddress = accountMetas[instruction.programAddressIndex]?.address;
525
+ if (!programAddress) {
526
+ throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
527
+ }
528
+ const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
529
+ const { data } = instruction;
530
+ return {
531
+ programAddress,
532
+ ...accounts && accounts.length ? { accounts } : {},
533
+ ...data && data.length ? { data } : {}
534
+ };
535
+ }
536
+ function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
537
+ if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
538
+ return {
539
+ blockhash: messageLifetimeToken,
540
+ lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
541
+ // U64 MAX
542
+ };
543
+ } else {
544
+ const nonceAccountAddress = firstInstruction.accounts[0].address;
545
+ addresses.assertIsAddress(nonceAccountAddress);
546
+ const nonceAuthorityAddress = firstInstruction.accounts[2].address;
547
+ addresses.assertIsAddress(nonceAuthorityAddress);
548
+ return {
549
+ nonce: messageLifetimeToken,
550
+ nonceAccountAddress,
551
+ nonceAuthorityAddress
552
+ };
553
+ }
554
+ }
555
+ function convertSignatures(compiledTransaction) {
556
+ const {
557
+ compiledMessage: { staticAccounts },
558
+ signatures
559
+ } = compiledTransaction;
560
+ return signatures.reduce((acc, sig, index) => {
561
+ const allZeros = sig.every((byte) => byte === 0);
562
+ if (allZeros)
563
+ return acc;
564
+ const address = staticAccounts[index];
565
+ return { ...acc, [address]: sig };
566
+ }, {});
567
+ }
568
+ function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
569
+ const { compiledMessage } = compiledTransaction;
570
+ if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
571
+ throw new Error("Cannot convert transaction with addressTableLookups");
572
+ }
573
+ const feePayer = compiledMessage.staticAccounts[0];
574
+ if (!feePayer)
575
+ throw new Error("No fee payer set in CompiledTransaction");
576
+ const accountMetas = getAccountMetas(compiledMessage);
577
+ const instructions = compiledMessage.instructions.map(
578
+ (compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
579
+ );
580
+ const firstInstruction = instructions[0];
581
+ const lifetimeConstraint = getLifetimeConstraint(
582
+ compiledMessage.lifetimeToken,
583
+ firstInstruction,
584
+ lastValidBlockHeight
585
+ );
586
+ const signatures = convertSignatures(compiledTransaction);
587
+ return functional.pipe(
588
+ createTransaction({ version: compiledMessage.version }),
589
+ (tx) => setTransactionFeePayer(feePayer, tx),
590
+ (tx) => instructions.reduce((acc, instruction) => {
591
+ return appendTransactionInstruction(instruction, acc);
592
+ }, tx),
593
+ (tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
594
+ (tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
595
+ );
596
+ }
469
597
  var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
470
598
  var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
471
599
  var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
@@ -496,6 +624,32 @@ function getAddressTableLookupEncoder() {
496
624
  }
497
625
  return memoizedAddressTableLookupEncoder;
498
626
  }
627
+ var memoizedAddressTableLookupDecoder;
628
+ function getAddressTableLookupDecoder() {
629
+ if (!memoizedAddressTableLookupDecoder) {
630
+ memoizedAddressTableLookupDecoder = codecsDataStructures.getStructDecoder(
631
+ [
632
+ ["lookupTableAddress", addresses.getAddressDecoder({ description: lookupTableAddressDescription })],
633
+ [
634
+ "writableIndices",
635
+ codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), {
636
+ description: writableIndicesDescription,
637
+ size: codecsNumbers.getShortU16Decoder()
638
+ })
639
+ ],
640
+ [
641
+ "readableIndices",
642
+ codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), {
643
+ description: readableIndicesDescription,
644
+ size: codecsNumbers.getShortU16Decoder()
645
+ })
646
+ ]
647
+ ],
648
+ { description: addressTableLookupDescription }
649
+ );
650
+ }
651
+ return memoizedAddressTableLookupDecoder;
652
+ }
499
653
  var memoizedU8Encoder;
500
654
  function getMemoizedU8Encoder() {
501
655
  if (!memoizedU8Encoder)
@@ -509,6 +663,19 @@ function getMemoizedU8EncoderDescription(description) {
509
663
  description: description ?? encoder.description
510
664
  };
511
665
  }
666
+ var memoizedU8Decoder;
667
+ function getMemoizedU8Decoder() {
668
+ if (!memoizedU8Decoder)
669
+ memoizedU8Decoder = codecsNumbers.getU8Decoder();
670
+ return memoizedU8Decoder;
671
+ }
672
+ function getMemoizedU8DecoderDescription(description) {
673
+ const decoder = getMemoizedU8Decoder();
674
+ return {
675
+ ...decoder,
676
+ description: description ?? decoder.description
677
+ };
678
+ }
512
679
  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;
513
680
  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;
514
681
  var numReadonlyNonSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable" : void 0;
@@ -525,6 +692,18 @@ function getMessageHeaderEncoder() {
525
692
  }
526
693
  );
527
694
  }
695
+ function getMessageHeaderDecoder() {
696
+ return codecsDataStructures.getStructDecoder(
697
+ [
698
+ ["numSignerAccounts", getMemoizedU8DecoderDescription(numSignerAccountsDescription)],
699
+ ["numReadonlySignerAccounts", getMemoizedU8DecoderDescription(numReadonlySignerAccountsDescription)],
700
+ ["numReadonlyNonSignerAccounts", getMemoizedU8DecoderDescription(numReadonlyNonSignerAccountsDescription)]
701
+ ],
702
+ {
703
+ description: messageHeaderDescription
704
+ }
705
+ );
706
+ }
528
707
  var programAddressIndexDescription = __DEV__ ? "The index of the program being called, according to the well-ordered accounts list for this transaction" : "programAddressIndex";
529
708
  var accountIndexDescription = __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : void 0;
530
709
  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";
@@ -559,12 +738,52 @@ function getInstructionEncoder() {
559
738
  }
560
739
  return memoizedGetInstructionEncoder;
561
740
  }
741
+ var memoizedGetInstructionDecoder;
742
+ function getInstructionDecoder() {
743
+ if (!memoizedGetInstructionDecoder) {
744
+ memoizedGetInstructionDecoder = codecsCore.mapDecoder(
745
+ codecsDataStructures.getStructDecoder([
746
+ ["programAddressIndex", codecsNumbers.getU8Decoder({ description: programAddressIndexDescription })],
747
+ [
748
+ "accountIndices",
749
+ codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder({ description: accountIndexDescription }), {
750
+ description: accountIndicesDescription,
751
+ size: codecsNumbers.getShortU16Decoder()
752
+ })
753
+ ],
754
+ ["data", codecsDataStructures.getBytesDecoder({ description: dataDescription, size: codecsNumbers.getShortU16Decoder() })]
755
+ ]),
756
+ // Convert an instruction to exclude optional fields if they are empty
757
+ (instruction) => {
758
+ if (instruction.accountIndices.length && instruction.data.byteLength) {
759
+ return instruction;
760
+ }
761
+ const { accountIndices, data, ...rest } = instruction;
762
+ return {
763
+ ...rest,
764
+ ...accountIndices.length ? { accountIndices } : null,
765
+ ...data.byteLength ? { data } : null
766
+ };
767
+ }
768
+ );
769
+ }
770
+ return memoizedGetInstructionDecoder;
771
+ }
562
772
  var VERSION_FLAG_MASK = 128;
563
773
  var BASE_CONFIG = {
564
774
  description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
565
775
  fixedSize: null,
566
776
  maxSize: 1
567
777
  };
778
+ function decode(bytes, offset = 0) {
779
+ const firstByte = bytes[offset];
780
+ if ((firstByte & VERSION_FLAG_MASK) === 0) {
781
+ return ["legacy", offset];
782
+ } else {
783
+ const version = firstByte ^ VERSION_FLAG_MASK;
784
+ return [version, offset + 1];
785
+ }
786
+ }
568
787
  function encode(value) {
569
788
  if (value === "legacy") {
570
789
  return new Uint8Array();
@@ -574,6 +793,12 @@ function encode(value) {
574
793
  }
575
794
  return new Uint8Array([value | VERSION_FLAG_MASK]);
576
795
  }
796
+ function getTransactionVersionDecoder() {
797
+ return {
798
+ ...BASE_CONFIG,
799
+ decode
800
+ };
801
+ }
577
802
  function getTransactionVersionEncoder() {
578
803
  return {
579
804
  ...BASE_CONFIG,
@@ -634,12 +859,47 @@ function getPreludeStructEncoderTuple() {
634
859
  ]
635
860
  ];
636
861
  }
862
+ function getPreludeStructDecoderTuple() {
863
+ return [
864
+ ["version", getTransactionVersionDecoder()],
865
+ ["header", getMessageHeaderDecoder()],
866
+ [
867
+ "staticAccounts",
868
+ codecsDataStructures.getArrayDecoder(addresses.getAddressDecoder(), {
869
+ description: staticAccountsDescription,
870
+ size: codecsNumbers.getShortU16Decoder()
871
+ })
872
+ ],
873
+ [
874
+ "lifetimeToken",
875
+ codecsStrings.getStringDecoder({
876
+ description: lifetimeTokenDescription,
877
+ encoding: codecsStrings.getBase58Decoder(),
878
+ size: 32
879
+ })
880
+ ],
881
+ [
882
+ "instructions",
883
+ codecsDataStructures.getArrayDecoder(getInstructionDecoder(), {
884
+ description: instructionsDescription,
885
+ size: codecsNumbers.getShortU16Decoder()
886
+ })
887
+ ],
888
+ ["addressTableLookups", getAddressTableLookupArrayDecoder()]
889
+ ];
890
+ }
637
891
  function getAddressTableLookupArrayEncoder() {
638
892
  return codecsDataStructures.getArrayEncoder(getAddressTableLookupEncoder(), {
639
893
  description: addressTableLookupsDescription,
640
894
  size: codecsNumbers.getShortU16Encoder()
641
895
  });
642
896
  }
897
+ function getAddressTableLookupArrayDecoder() {
898
+ return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), {
899
+ description: addressTableLookupsDescription,
900
+ size: codecsNumbers.getShortU16Decoder()
901
+ });
902
+ }
643
903
  var messageDescription = __DEV__ ? "The wire format of a Solana transaction message" : "message";
644
904
  function getCompiledMessageEncoder() {
645
905
  return {
@@ -655,10 +915,23 @@ function getCompiledMessageEncoder() {
655
915
  maxSize: null
656
916
  };
657
917
  }
918
+ function getCompiledMessageDecoder() {
919
+ return codecsCore.mapDecoder(
920
+ codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple(), {
921
+ description: messageDescription
922
+ }),
923
+ ({ addressTableLookups, ...restOfMessage }) => {
924
+ if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
925
+ return restOfMessage;
926
+ }
927
+ return { ...restOfMessage, addressTableLookups };
928
+ }
929
+ );
930
+ }
658
931
 
659
932
  // src/serializers/transaction.ts
660
- var transactionDescription = __DEV__ ? "The wire format of a Solana transaction" : "transaction";
661
933
  var signaturesDescription = __DEV__ ? "A compact array of 64-byte, base-64 encoded Ed25519 signatures" : "signatures";
934
+ var transactionDescription = __DEV__ ? "The wire format of a Solana transaction" : "transaction";
662
935
  function getCompiledTransactionEncoder() {
663
936
  return codecsDataStructures.getStructEncoder(
664
937
  [
@@ -676,9 +949,38 @@ function getCompiledTransactionEncoder() {
676
949
  }
677
950
  );
678
951
  }
952
+ function getSignatureDecoder() {
953
+ return codecsCore.mapDecoder(codecsDataStructures.getBytesDecoder({ size: 64 }), (bytes) => bytes);
954
+ }
955
+ function getCompiledTransactionDecoder() {
956
+ return codecsDataStructures.getStructDecoder(
957
+ [
958
+ [
959
+ "signatures",
960
+ codecsDataStructures.getArrayDecoder(getSignatureDecoder(), {
961
+ description: signaturesDescription,
962
+ size: codecsNumbers.getShortU16Decoder()
963
+ })
964
+ ],
965
+ ["compiledMessage", getCompiledMessageDecoder()]
966
+ ],
967
+ {
968
+ description: transactionDescription
969
+ }
970
+ );
971
+ }
679
972
  function getTransactionEncoder() {
680
973
  return codecsCore.mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
681
974
  }
975
+ function getTransactionDecoder(lastValidBlockHeight) {
976
+ return codecsCore.mapDecoder(
977
+ getCompiledTransactionDecoder(),
978
+ (compiledTransaction) => decompileTransaction(compiledTransaction, lastValidBlockHeight)
979
+ );
980
+ }
981
+ function getTransactionCodec(lastValidBlockHeight) {
982
+ return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
983
+ }
682
984
  function assertIsTransactionSignature(putativeTransactionSignature) {
683
985
  try {
684
986
  if (
@@ -754,6 +1056,15 @@ function transactionSignature(putativeTransactionSignature) {
754
1056
  assertIsTransactionSignature(putativeTransactionSignature);
755
1057
  return putativeTransactionSignature;
756
1058
  }
1059
+ function assertTransactionIsFullySigned(transaction) {
1060
+ const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
1061
+ const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
1062
+ requiredSigners.forEach((address) => {
1063
+ if (!transaction.signatures[address]) {
1064
+ throw new Error(`Transaction is missing signature for address \`${address}\``);
1065
+ }
1066
+ });
1067
+ }
757
1068
 
758
1069
  // src/wire-transaction.ts
759
1070
  function getBase64EncodedWireTransaction(transaction) {
@@ -767,9 +1078,12 @@ exports.appendTransactionInstruction = appendTransactionInstruction;
767
1078
  exports.assertIsBlockhash = assertIsBlockhash;
768
1079
  exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
769
1080
  exports.assertIsTransactionSignature = assertIsTransactionSignature;
1081
+ exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
770
1082
  exports.createTransaction = createTransaction;
771
1083
  exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
772
1084
  exports.getSignatureFromTransaction = getSignatureFromTransaction;
1085
+ exports.getTransactionCodec = getTransactionCodec;
1086
+ exports.getTransactionDecoder = getTransactionDecoder;
773
1087
  exports.getTransactionEncoder = getTransactionEncoder;
774
1088
  exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
775
1089
  exports.isTransactionSignature = isTransactionSignature;
@@ -779,5 +1093,3 @@ exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockh
779
1093
  exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
780
1094
  exports.signTransaction = signTransaction;
781
1095
  exports.transactionSignature = transactionSignature;
782
- //# sourceMappingURL=out.js.map
783
- //# sourceMappingURL=index.browser.cjs.map