@solana/transactions 2.0.0-experimental.ce179f2 → 2.0.0-experimental.cf6ca9d

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.
@@ -1,10 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  var umiSerializers = require('@metaplex-foundation/umi-serializers');
4
- var addresses = require('@solana/addresses');
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');
9
+ var codecsStrings = require('@solana/codecs-strings');
8
10
  var keys = require('@solana/keys');
9
11
 
10
12
  // ../build-scripts/env-shim.ts
@@ -34,8 +36,8 @@ function assertIsBlockhash(putativeBlockhash) {
34
36
  ) {
35
37
  throw new Error("Expected input string to decode to a byte array of length 32.");
36
38
  }
37
- const bytes2 = umiSerializers.base58.serialize(putativeBlockhash);
38
- const numBytes = bytes2.byteLength;
39
+ const bytes = umiSerializers.base58.serialize(putativeBlockhash);
40
+ const numBytes = bytes.byteLength;
39
41
  if (numBytes !== 32) {
40
42
  throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
41
43
  }
@@ -120,7 +122,7 @@ function isAdvanceNonceAccountInstruction(instruction) {
120
122
  instruction.accounts?.length === 3 && // First account is nonce account address
121
123
  instruction.accounts[0].address != null && instruction.accounts[0].role === AccountRole.WRITABLE && // Second account is recent blockhashes sysvar
122
124
  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;
125
+ instruction.accounts[2].address != null && isSignerRole(instruction.accounts[2].role);
124
126
  }
125
127
  function isAdvanceNonceAccountInstructionData(data) {
126
128
  return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;
@@ -128,21 +130,38 @@ function isAdvanceNonceAccountInstructionData(data) {
128
130
  function isDurableNonceTransaction(transaction) {
129
131
  return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
130
132
  }
133
+ function isAdvanceNonceAccountInstructionForNonce(instruction, nonceAccountAddress, nonceAuthorityAddress) {
134
+ return instruction.accounts[0].address === nonceAccountAddress && instruction.accounts[2].address === nonceAuthorityAddress;
135
+ }
131
136
  function setTransactionLifetimeUsingDurableNonce({
132
137
  nonce,
133
138
  nonceAccountAddress,
134
139
  nonceAuthorityAddress
135
140
  }, 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;
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
+ ];
139
161
  }
140
162
  const out = {
141
163
  ...getUnsignedTransaction(transaction),
142
- instructions: [
143
- createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
144
- ...isAlreadyDurableNonceTransaction ? transaction.instructions.slice(1) : transaction.instructions
145
- ],
164
+ instructions: newInstructions,
146
165
  lifetimeConstraint: {
147
166
  nonce
148
167
  }
@@ -465,6 +484,116 @@ function getCompiledTransaction(transaction) {
465
484
  signatures
466
485
  };
467
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
+ }
468
597
  var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
469
598
  var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
470
599
  var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
@@ -521,32 +650,54 @@ function getAddressTableLookupDecoder() {
521
650
  }
522
651
  return memoizedAddressTableLookupDecoder;
523
652
  }
524
- function getAddressTableLookupCodec() {
525
- return codecsCore.combineCodec(getAddressTableLookupEncoder(), getAddressTableLookupDecoder());
653
+ var memoizedU8Encoder;
654
+ function getMemoizedU8Encoder() {
655
+ if (!memoizedU8Encoder)
656
+ memoizedU8Encoder = codecsNumbers.getU8Encoder();
657
+ return memoizedU8Encoder;
526
658
  }
527
- var memoizedU8Codec;
528
- function getMemoizedU8Codec() {
529
- if (!memoizedU8Codec)
530
- memoizedU8Codec = codecsNumbers.getU8Codec();
531
- return memoizedU8Codec;
659
+ function getMemoizedU8EncoderDescription(description) {
660
+ const encoder = getMemoizedU8Encoder();
661
+ return {
662
+ ...encoder,
663
+ description: description ?? encoder.description
664
+ };
532
665
  }
533
- function getMemoizedU8CodecDescription(description) {
534
- const codec = getMemoizedU8Codec();
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();
535
674
  return {
536
- ...codec,
537
- description: description ?? codec.description
675
+ ...decoder,
676
+ description: description ?? decoder.description
538
677
  };
539
678
  }
540
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;
541
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;
542
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;
543
682
  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(
683
+ function getMessageHeaderEncoder() {
684
+ return codecsDataStructures.getStructEncoder(
546
685
  [
547
- ["numSignerAccounts", getMemoizedU8CodecDescription(numSignerAccountsDescription)],
548
- ["numReadonlySignerAccounts", getMemoizedU8CodecDescription(numReadonlySignerAccountsDescription)],
549
- ["numReadonlyNonSignerAccounts", getMemoizedU8CodecDescription(numReadonlyNonSignerAccountsDescription)]
686
+ ["numSignerAccounts", getMemoizedU8EncoderDescription(numSignerAccountsDescription)],
687
+ ["numReadonlySignerAccounts", getMemoizedU8EncoderDescription(numReadonlySignerAccountsDescription)],
688
+ ["numReadonlyNonSignerAccounts", getMemoizedU8EncoderDescription(numReadonlyNonSignerAccountsDescription)]
689
+ ],
690
+ {
691
+ description: messageHeaderDescription
692
+ }
693
+ );
694
+ }
695
+ function getMessageHeaderDecoder() {
696
+ return codecsDataStructures.getStructDecoder(
697
+ [
698
+ ["numSignerAccounts", getMemoizedU8DecoderDescription(numSignerAccountsDescription)],
699
+ ["numReadonlySignerAccounts", getMemoizedU8DecoderDescription(numReadonlySignerAccountsDescription)],
700
+ ["numReadonlyNonSignerAccounts", getMemoizedU8DecoderDescription(numReadonlyNonSignerAccountsDescription)]
550
701
  ],
551
702
  {
552
703
  description: messageHeaderDescription
@@ -618,17 +769,14 @@ function getInstructionDecoder() {
618
769
  }
619
770
  return memoizedGetInstructionDecoder;
620
771
  }
621
- function getInstructionCodec() {
622
- return codecsCore.combineCodec(getInstructionEncoder(), getInstructionDecoder());
623
- }
624
772
  var VERSION_FLAG_MASK = 128;
625
773
  var BASE_CONFIG = {
626
774
  description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
627
775
  fixedSize: null,
628
776
  maxSize: 1
629
777
  };
630
- function decode(bytes2, offset = 0) {
631
- const firstByte = bytes2[offset];
778
+ function decode(bytes, offset = 0) {
779
+ const firstByte = bytes[offset];
632
780
  if ((firstByte & VERSION_FLAG_MASK) === 0) {
633
781
  return ["legacy", offset];
634
782
  } else {
@@ -657,126 +805,181 @@ function getTransactionVersionEncoder() {
657
805
  encode
658
806
  };
659
807
  }
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
808
 
677
809
  // 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
- }
810
+ var staticAccountsDescription = __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "staticAccounts";
811
+ var lifetimeTokenDescription = __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "lifetimeToken";
812
+ var instructionsDescription = __DEV__ ? "A compact-array of instructions belonging to this transaction" : "instructions";
813
+ var addressTableLookupsDescription = __DEV__ ? "A compact array of address table lookups belonging to this transaction" : "addressTableLookups";
814
+ function getCompiledMessageLegacyEncoder() {
815
+ return codecsDataStructures.getStructEncoder(getPreludeStructEncoderTuple());
703
816
  }
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
- };
817
+ function getCompiledMessageVersionedEncoder() {
818
+ return codecsCore.mapEncoder(
819
+ codecsDataStructures.getStructEncoder([
820
+ ...getPreludeStructEncoderTuple(),
821
+ ["addressTableLookups", getAddressTableLookupArrayEncoder()]
822
+ ]),
823
+ (value) => {
824
+ if (value.version === "legacy") {
825
+ return value;
826
+ }
827
+ return {
828
+ ...value,
829
+ addressTableLookups: value.addressTableLookups ?? []
830
+ };
831
+ }
832
+ );
712
833
  }
713
- function getPreludeStructSerializerTuple() {
834
+ function getPreludeStructEncoderTuple() {
714
835
  return [
715
- ["version", toSerializer(getTransactionVersionCodec())],
716
- ["header", toSerializer(getMessageHeaderCodec())],
836
+ ["version", getTransactionVersionEncoder()],
837
+ ["header", getMessageHeaderEncoder()],
717
838
  [
718
839
  "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()
840
+ codecsDataStructures.getArrayEncoder(addresses.getAddressEncoder(), {
841
+ description: staticAccountsDescription,
842
+ size: codecsNumbers.getShortU16Encoder()
722
843
  })
723
844
  ],
724
845
  [
725
846
  "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,
847
+ codecsStrings.getStringEncoder({
848
+ description: lifetimeTokenDescription,
849
+ encoding: codecsStrings.getBase58Encoder(),
729
850
  size: 32
730
851
  })
731
852
  ],
732
853
  [
733
854
  "instructions",
734
- umiSerializers.array(toSerializer(getInstructionCodec()), {
735
- description: __DEV__ ? "A compact-array of instructions belonging to this transaction" : "",
736
- size: umiSerializers.shortU16()
855
+ codecsDataStructures.getArrayEncoder(getInstructionEncoder(), {
856
+ description: instructionsDescription,
857
+ size: codecsNumbers.getShortU16Encoder()
737
858
  })
738
859
  ]
739
860
  ];
740
861
  }
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()
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
+ }
891
+ function getAddressTableLookupArrayEncoder() {
892
+ return codecsDataStructures.getArrayEncoder(getAddressTableLookupEncoder(), {
893
+ description: addressTableLookupsDescription,
894
+ size: codecsNumbers.getShortU16Encoder()
745
895
  });
746
896
  }
897
+ function getAddressTableLookupArrayDecoder() {
898
+ return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), {
899
+ description: addressTableLookupsDescription,
900
+ size: codecsNumbers.getShortU16Decoder()
901
+ });
902
+ }
903
+ var messageDescription = __DEV__ ? "The wire format of a Solana transaction message" : "message";
747
904
  function getCompiledMessageEncoder() {
748
905
  return {
749
- ...BASE_CONFIG2,
750
- deserialize: getUnimplementedDecoder("CompiledMessage"),
751
- serialize
906
+ description: messageDescription,
907
+ encode: (compiledMessage) => {
908
+ if (compiledMessage.version === "legacy") {
909
+ return getCompiledMessageLegacyEncoder().encode(compiledMessage);
910
+ } else {
911
+ return getCompiledMessageVersionedEncoder().encode(compiledMessage);
912
+ }
913
+ },
914
+ fixedSize: null,
915
+ maxSize: null
752
916
  };
753
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
+ }
754
931
 
755
932
  // 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([
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";
935
+ function getCompiledTransactionEncoder() {
936
+ return codecsDataStructures.getStructEncoder(
764
937
  [
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
- })
938
+ [
939
+ "signatures",
940
+ codecsDataStructures.getArrayEncoder(codecsDataStructures.getBytesEncoder({ size: 64 }), {
941
+ description: signaturesDescription,
942
+ size: codecsNumbers.getShortU16Encoder()
943
+ })
944
+ ],
945
+ ["compiledMessage", getCompiledMessageEncoder()]
770
946
  ],
771
- ["compiledMessage", getCompiledMessageEncoder()]
772
- ]).serialize(compiledTransaction);
947
+ {
948
+ description: transactionDescription
949
+ }
950
+ );
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
+ );
773
971
  }
774
972
  function getTransactionEncoder() {
775
- return {
776
- ...BASE_CONFIG3,
777
- deserialize: getUnimplementedDecoder("CompiledMessage"),
778
- serialize: serialize2
779
- };
973
+ return codecsCore.mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
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));
780
983
  }
781
984
  function assertIsTransactionSignature(putativeTransactionSignature) {
782
985
  try {
@@ -787,8 +990,8 @@ function assertIsTransactionSignature(putativeTransactionSignature) {
787
990
  ) {
788
991
  throw new Error("Expected input string to decode to a byte array of length 64.");
789
992
  }
790
- const bytes2 = umiSerializers.base58.serialize(putativeTransactionSignature);
791
- const numBytes = bytes2.byteLength;
993
+ const bytes = umiSerializers.base58.serialize(putativeTransactionSignature);
994
+ const numBytes = bytes.byteLength;
792
995
  if (numBytes !== 64) {
793
996
  throw new Error(`Expected input string to decode to a byte array of length 64. Actual length: ${numBytes}`);
794
997
  }
@@ -806,18 +1009,13 @@ function isTransactionSignature(putativeTransactionSignature) {
806
1009
  ) {
807
1010
  return false;
808
1011
  }
809
- const bytes2 = umiSerializers.base58.serialize(putativeTransactionSignature);
810
- const numBytes = bytes2.byteLength;
1012
+ const bytes = umiSerializers.base58.serialize(putativeTransactionSignature);
1013
+ const numBytes = bytes.byteLength;
811
1014
  if (numBytes !== 64) {
812
1015
  return false;
813
1016
  }
814
1017
  return true;
815
1018
  }
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
1019
  function getSignatureFromTransaction(transaction) {
822
1020
  const signatureBytes = transaction.signatures[transaction.feePayer];
823
1021
  if (!signatureBytes) {
@@ -831,12 +1029,10 @@ function getSignatureFromTransaction(transaction) {
831
1029
  async function signTransaction(keyPairs, transaction) {
832
1030
  const compiledMessage = compileMessage(transaction);
833
1031
  const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
1032
+ const wireMessageBytes = getCompiledMessageEncoder().encode(compiledMessage);
834
1033
  const publicKeySignaturePairs = await Promise.all(
835
1034
  keyPairs.map(
836
- (keyPair) => Promise.all([
837
- addresses.getAddressFromPublicKey(keyPair.publicKey),
838
- getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
839
- ])
1035
+ (keyPair) => Promise.all([addresses.getAddressFromPublicKey(keyPair.publicKey), keys.signBytes(keyPair.privateKey, wireMessageBytes)])
840
1036
  )
841
1037
  );
842
1038
  for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
@@ -853,10 +1049,19 @@ function transactionSignature(putativeTransactionSignature) {
853
1049
  assertIsTransactionSignature(putativeTransactionSignature);
854
1050
  return putativeTransactionSignature;
855
1051
  }
1052
+ function assertTransactionIsFullySigned(transaction) {
1053
+ const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
1054
+ const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
1055
+ requiredSigners.forEach((address) => {
1056
+ if (!transaction.signatures[address]) {
1057
+ throw new Error(`Transaction is missing signature for address \`${address}\``);
1058
+ }
1059
+ });
1060
+ }
856
1061
 
857
1062
  // src/wire-transaction.ts
858
1063
  function getBase64EncodedWireTransaction(transaction) {
859
- const wireTransactionBytes = getTransactionEncoder().serialize(transaction);
1064
+ const wireTransactionBytes = getTransactionEncoder().encode(transaction);
860
1065
  {
861
1066
  return btoa(String.fromCharCode(...wireTransactionBytes));
862
1067
  }
@@ -866,9 +1071,12 @@ exports.appendTransactionInstruction = appendTransactionInstruction;
866
1071
  exports.assertIsBlockhash = assertIsBlockhash;
867
1072
  exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
868
1073
  exports.assertIsTransactionSignature = assertIsTransactionSignature;
1074
+ exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
869
1075
  exports.createTransaction = createTransaction;
870
1076
  exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
871
1077
  exports.getSignatureFromTransaction = getSignatureFromTransaction;
1078
+ exports.getTransactionCodec = getTransactionCodec;
1079
+ exports.getTransactionDecoder = getTransactionDecoder;
872
1080
  exports.getTransactionEncoder = getTransactionEncoder;
873
1081
  exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
874
1082
  exports.isTransactionSignature = isTransactionSignature;
@@ -878,3 +1086,5 @@ exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockh
878
1086
  exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
879
1087
  exports.signTransaction = signTransaction;
880
1088
  exports.transactionSignature = transactionSignature;
1089
+ //# sourceMappingURL=out.js.map
1090
+ //# sourceMappingURL=index.browser.cjs.map