@solana/transactions 2.0.0-experimental.a9e6db3 → 2.0.0-experimental.aa4a701

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 (60) hide show
  1. package/README.md +272 -5
  2. package/dist/index.browser.cjs +465 -257
  3. package/dist/index.browser.cjs.map +1 -1
  4. package/dist/index.browser.js +463 -257
  5. package/dist/index.browser.js.map +1 -1
  6. package/dist/index.development.js +900 -991
  7. package/dist/index.development.js.map +1 -1
  8. package/dist/index.native.js +463 -257
  9. package/dist/index.native.js.map +1 -1
  10. package/dist/index.node.cjs +465 -257
  11. package/dist/index.node.cjs.map +1 -1
  12. package/dist/index.node.js +463 -257
  13. package/dist/index.node.js.map +1 -1
  14. package/dist/index.production.min.js +18 -16
  15. package/dist/types/accounts.d.ts +2 -2
  16. package/dist/types/accounts.d.ts.map +1 -0
  17. package/dist/types/blockhash.d.ts.map +1 -0
  18. package/dist/types/compilable-transaction.d.ts +7 -0
  19. package/dist/types/compilable-transaction.d.ts.map +1 -0
  20. package/dist/types/compile-address-table-lookups.d.ts +2 -2
  21. package/dist/types/compile-address-table-lookups.d.ts.map +1 -0
  22. package/dist/types/compile-header.d.ts.map +1 -0
  23. package/dist/types/compile-instructions.d.ts.map +1 -0
  24. package/dist/types/compile-lifetime-token.d.ts.map +1 -0
  25. package/dist/types/compile-static-accounts.d.ts +2 -2
  26. package/dist/types/compile-static-accounts.d.ts.map +1 -0
  27. package/dist/types/compile-transaction.d.ts +5 -6
  28. package/dist/types/compile-transaction.d.ts.map +1 -0
  29. package/dist/types/create-transaction.d.ts.map +1 -0
  30. package/dist/types/decompile-transaction.d.ts +5 -0
  31. package/dist/types/decompile-transaction.d.ts.map +1 -0
  32. package/dist/types/durable-nonce.d.ts +6 -6
  33. package/dist/types/durable-nonce.d.ts.map +1 -0
  34. package/dist/types/fee-payer.d.ts +4 -4
  35. package/dist/types/fee-payer.d.ts.map +1 -0
  36. package/dist/types/index.d.ts +1 -0
  37. package/dist/types/index.d.ts.map +1 -0
  38. package/dist/types/instructions.d.ts.map +1 -0
  39. package/dist/types/message.d.ts +1 -5
  40. package/dist/types/message.d.ts.map +1 -0
  41. package/dist/types/serializers/address-table-lookup.d.ts +5 -3
  42. package/dist/types/serializers/address-table-lookup.d.ts.map +1 -0
  43. package/dist/types/serializers/header.d.ts.map +1 -0
  44. package/dist/types/serializers/index.d.ts.map +1 -0
  45. package/dist/types/serializers/instruction.d.ts +4 -2
  46. package/dist/types/serializers/instruction.d.ts.map +1 -0
  47. package/dist/types/serializers/message.d.ts +4 -4
  48. package/dist/types/serializers/message.d.ts.map +1 -0
  49. package/dist/types/serializers/transaction-version.d.ts.map +1 -0
  50. package/dist/types/serializers/transaction.d.ts +6 -5
  51. package/dist/types/serializers/transaction.d.ts.map +1 -0
  52. package/dist/types/signatures.d.ts +8 -12
  53. package/dist/types/signatures.d.ts.map +1 -0
  54. package/dist/types/types.d.ts +6 -13
  55. package/dist/types/types.d.ts.map +1 -0
  56. package/dist/types/unsigned-transaction.d.ts.map +1 -0
  57. package/dist/types/wire-transaction.d.ts +1 -1
  58. package/dist/types/wire-transaction.d.ts.map +1 -0
  59. package/package.json +14 -13
  60. package/dist/types/serializers/unimplemented.d.ts +0 -3
@@ -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');
4
+ var codecsCore = require('@solana/codecs-core');
5
5
  var codecsDataStructures = require('@solana/codecs-data-structures');
6
6
  var codecsNumbers = require('@solana/codecs-numbers');
7
- var codecsCore = require('@solana/codecs-core');
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 bytes3 = umiSerializers.base58.serialize(putativeBlockhash);
38
- const numBytes = bytes3.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,142 +486,299 @@ function getCompiledTransaction(transaction) {
465
486
  signatures
466
487
  };
467
488
  }
468
- function addressSerializerCompat(compat) {
469
- const codec = addresses.getAddressCodec();
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;
470
532
  return {
471
- description: compat?.description ?? codec.description,
472
- deserialize: codec.decode,
473
- fixedSize: codec.fixedSize,
474
- maxSize: codec.maxSize,
475
- serialize: codec.encode
533
+ programAddress,
534
+ ...accounts && accounts.length ? { accounts } : {},
535
+ ...data && data.length ? { data } : {}
476
536
  };
477
537
  }
478
- function getAddressTableLookupCodec() {
479
- return umiSerializers.struct(
480
- [
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
+ }
599
+ var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
600
+ var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
601
+ var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
602
+ 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";
603
+ var memoizedAddressTableLookupEncoder;
604
+ function getAddressTableLookupEncoder() {
605
+ if (!memoizedAddressTableLookupEncoder) {
606
+ memoizedAddressTableLookupEncoder = codecsDataStructures.getStructEncoder(
481
607
  [
482
- "lookupTableAddress",
483
- addressSerializerCompat(
484
- __DEV__ ? {
485
- description: "The address of the address lookup table account from which instruction addresses should be looked up"
486
- } : void 0
487
- )
608
+ ["lookupTableAddress", addresses.getAddressEncoder({ description: lookupTableAddressDescription })],
609
+ [
610
+ "writableIndices",
611
+ codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), {
612
+ description: writableIndicesDescription,
613
+ size: codecsNumbers.getShortU16Encoder()
614
+ })
615
+ ],
616
+ [
617
+ "readableIndices",
618
+ codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), {
619
+ description: readableIndicesDescription,
620
+ size: codecsNumbers.getShortU16Encoder()
621
+ })
622
+ ]
488
623
  ],
624
+ { description: addressTableLookupDescription }
625
+ );
626
+ }
627
+ return memoizedAddressTableLookupEncoder;
628
+ }
629
+ var memoizedAddressTableLookupDecoder;
630
+ function getAddressTableLookupDecoder() {
631
+ if (!memoizedAddressTableLookupDecoder) {
632
+ memoizedAddressTableLookupDecoder = codecsDataStructures.getStructDecoder(
489
633
  [
490
- "writableIndices",
491
- umiSerializers.array(umiSerializers.u8(), {
492
- ...__DEV__ ? {
493
- description: "The indices of the accounts in the lookup table that should be loaded as writeable"
494
- } : null,
495
- size: umiSerializers.shortU16()
496
- })
634
+ ["lookupTableAddress", addresses.getAddressDecoder({ description: lookupTableAddressDescription })],
635
+ [
636
+ "writableIndices",
637
+ codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), {
638
+ description: writableIndicesDescription,
639
+ size: codecsNumbers.getShortU16Decoder()
640
+ })
641
+ ],
642
+ [
643
+ "readableIndices",
644
+ codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), {
645
+ description: readableIndicesDescription,
646
+ size: codecsNumbers.getShortU16Decoder()
647
+ })
648
+ ]
497
649
  ],
498
- [
499
- "readableIndices",
500
- umiSerializers.array(umiSerializers.u8(), {
501
- ...__DEV__ ? {
502
- description: "The indices of the accounts in the lookup table that should be loaded as read-only"
503
- } : void 0,
504
- size: umiSerializers.shortU16()
505
- })
506
- ]
507
- ],
508
- __DEV__ ? {
509
- description: "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"
510
- } : void 0
511
- );
650
+ { description: addressTableLookupDescription }
651
+ );
652
+ }
653
+ return memoizedAddressTableLookupDecoder;
654
+ }
655
+ var memoizedU8Encoder;
656
+ function getMemoizedU8Encoder() {
657
+ if (!memoizedU8Encoder)
658
+ memoizedU8Encoder = codecsNumbers.getU8Encoder();
659
+ return memoizedU8Encoder;
660
+ }
661
+ function getMemoizedU8EncoderDescription(description) {
662
+ const encoder = getMemoizedU8Encoder();
663
+ return {
664
+ ...encoder,
665
+ description: description ?? encoder.description
666
+ };
512
667
  }
513
- var memoizedU8Codec;
514
- function getMemoizedU8Codec() {
515
- if (!memoizedU8Codec)
516
- memoizedU8Codec = codecsNumbers.getU8Codec();
517
- return memoizedU8Codec;
668
+ var memoizedU8Decoder;
669
+ function getMemoizedU8Decoder() {
670
+ if (!memoizedU8Decoder)
671
+ memoizedU8Decoder = codecsNumbers.getU8Decoder();
672
+ return memoizedU8Decoder;
518
673
  }
519
- function getMemoizedU8CodecDescription(description) {
520
- const codec = getMemoizedU8Codec();
674
+ function getMemoizedU8DecoderDescription(description) {
675
+ const decoder = getMemoizedU8Decoder();
521
676
  return {
522
- ...codec,
523
- description: description ?? codec.description
677
+ ...decoder,
678
+ description: description ?? decoder.description
524
679
  };
525
680
  }
526
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;
527
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;
528
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;
529
684
  var messageHeaderDescription = __DEV__ ? "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses" : void 0;
530
- function getMessageHeaderCodec() {
531
- return codecsDataStructures.getStructCodec(
685
+ function getMessageHeaderEncoder() {
686
+ return codecsDataStructures.getStructEncoder(
532
687
  [
533
- ["numSignerAccounts", getMemoizedU8CodecDescription(numSignerAccountsDescription)],
534
- ["numReadonlySignerAccounts", getMemoizedU8CodecDescription(numReadonlySignerAccountsDescription)],
535
- ["numReadonlyNonSignerAccounts", getMemoizedU8CodecDescription(numReadonlyNonSignerAccountsDescription)]
688
+ ["numSignerAccounts", getMemoizedU8EncoderDescription(numSignerAccountsDescription)],
689
+ ["numReadonlySignerAccounts", getMemoizedU8EncoderDescription(numReadonlySignerAccountsDescription)],
690
+ ["numReadonlyNonSignerAccounts", getMemoizedU8EncoderDescription(numReadonlyNonSignerAccountsDescription)]
536
691
  ],
537
692
  {
538
693
  description: messageHeaderDescription
539
694
  }
540
695
  );
541
696
  }
542
- function getInstructionCodec() {
543
- return umiSerializers.mapSerializer(
544
- umiSerializers.struct([
545
- [
546
- "programAddressIndex",
547
- umiSerializers.u8(
548
- __DEV__ ? {
549
- description: "The index of the program being called, according to the well-ordered accounts list for this transaction"
550
- } : void 0
551
- )
552
- ],
553
- [
554
- "accountIndices",
555
- umiSerializers.array(
556
- umiSerializers.u8({
557
- description: __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : ""
558
- }),
559
- {
560
- description: __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" : "",
561
- size: umiSerializers.shortU16()
562
- }
563
- )
564
- ],
565
- [
566
- "data",
567
- umiSerializers.bytes({
568
- description: __DEV__ ? "An optional buffer of data passed to the instruction" : "",
569
- size: umiSerializers.shortU16()
570
- })
571
- ]
572
- ]),
573
- (value) => {
574
- if (value.accountIndices !== void 0 && value.data !== void 0) {
575
- return value;
576
- }
577
- return {
578
- ...value,
579
- accountIndices: value.accountIndices ?? [],
580
- data: value.data ?? new Uint8Array(0)
581
- };
582
- },
583
- (value) => {
584
- if (value.accountIndices.length && value.data.byteLength) {
585
- return value;
586
- }
587
- const { accountIndices, data, ...rest } = value;
588
- return {
589
- ...rest,
590
- ...accountIndices.length ? { accountIndices } : null,
591
- ...data.byteLength ? { data } : null
592
- };
697
+ function getMessageHeaderDecoder() {
698
+ return codecsDataStructures.getStructDecoder(
699
+ [
700
+ ["numSignerAccounts", getMemoizedU8DecoderDescription(numSignerAccountsDescription)],
701
+ ["numReadonlySignerAccounts", getMemoizedU8DecoderDescription(numReadonlySignerAccountsDescription)],
702
+ ["numReadonlyNonSignerAccounts", getMemoizedU8DecoderDescription(numReadonlyNonSignerAccountsDescription)]
703
+ ],
704
+ {
705
+ description: messageHeaderDescription
593
706
  }
594
707
  );
595
708
  }
709
+ var programAddressIndexDescription = __DEV__ ? "The index of the program being called, according to the well-ordered accounts list for this transaction" : "programAddressIndex";
710
+ var accountIndexDescription = __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : void 0;
711
+ 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";
712
+ var dataDescription = __DEV__ ? "An optional buffer of data passed to the instruction" : "data";
713
+ var memoizedGetInstructionEncoder;
714
+ function getInstructionEncoder() {
715
+ if (!memoizedGetInstructionEncoder) {
716
+ memoizedGetInstructionEncoder = codecsCore.mapEncoder(
717
+ codecsDataStructures.getStructEncoder([
718
+ ["programAddressIndex", codecsNumbers.getU8Encoder({ description: programAddressIndexDescription })],
719
+ [
720
+ "accountIndices",
721
+ codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder({ description: accountIndexDescription }), {
722
+ description: accountIndicesDescription,
723
+ size: codecsNumbers.getShortU16Encoder()
724
+ })
725
+ ],
726
+ ["data", codecsDataStructures.getBytesEncoder({ description: dataDescription, size: codecsNumbers.getShortU16Encoder() })]
727
+ ]),
728
+ // Convert an instruction to have all fields defined
729
+ (instruction) => {
730
+ if (instruction.accountIndices !== void 0 && instruction.data !== void 0) {
731
+ return instruction;
732
+ }
733
+ return {
734
+ ...instruction,
735
+ accountIndices: instruction.accountIndices ?? [],
736
+ data: instruction.data ?? new Uint8Array(0)
737
+ };
738
+ }
739
+ );
740
+ }
741
+ return memoizedGetInstructionEncoder;
742
+ }
743
+ var memoizedGetInstructionDecoder;
744
+ function getInstructionDecoder() {
745
+ if (!memoizedGetInstructionDecoder) {
746
+ memoizedGetInstructionDecoder = codecsCore.mapDecoder(
747
+ codecsDataStructures.getStructDecoder([
748
+ ["programAddressIndex", codecsNumbers.getU8Decoder({ description: programAddressIndexDescription })],
749
+ [
750
+ "accountIndices",
751
+ codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder({ description: accountIndexDescription }), {
752
+ description: accountIndicesDescription,
753
+ size: codecsNumbers.getShortU16Decoder()
754
+ })
755
+ ],
756
+ ["data", codecsDataStructures.getBytesDecoder({ description: dataDescription, size: codecsNumbers.getShortU16Decoder() })]
757
+ ]),
758
+ // Convert an instruction to exclude optional fields if they are empty
759
+ (instruction) => {
760
+ if (instruction.accountIndices.length && instruction.data.byteLength) {
761
+ return instruction;
762
+ }
763
+ const { accountIndices, data, ...rest } = instruction;
764
+ return {
765
+ ...rest,
766
+ ...accountIndices.length ? { accountIndices } : null,
767
+ ...data.byteLength ? { data } : null
768
+ };
769
+ }
770
+ );
771
+ }
772
+ return memoizedGetInstructionDecoder;
773
+ }
596
774
  var VERSION_FLAG_MASK = 128;
597
775
  var BASE_CONFIG = {
598
776
  description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
599
777
  fixedSize: null,
600
778
  maxSize: 1
601
779
  };
602
- function decode(bytes3, offset = 0) {
603
- const firstByte = bytes3[offset];
780
+ function decode(bytes, offset = 0) {
781
+ const firstByte = bytes[offset];
604
782
  if ((firstByte & VERSION_FLAG_MASK) === 0) {
605
783
  return ["legacy", offset];
606
784
  } else {
@@ -629,185 +807,202 @@ function getTransactionVersionEncoder() {
629
807
  encode
630
808
  };
631
809
  }
632
- function getTransactionVersionCodec() {
633
- return codecsCore.combineCodec(getTransactionVersionEncoder(), getTransactionVersionDecoder());
634
- }
635
-
636
- // src/serializers/unimplemented.ts
637
- function getError(type, name) {
638
- const functionSuffix = name + type[0].toUpperCase() + type.slice(1);
639
- return new Error(
640
- `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}`
641
- );
642
- }
643
- function getUnimplementedDecoder(name) {
644
- return () => {
645
- throw getError("decoder", name);
646
- };
647
- }
648
810
 
649
811
  // src/serializers/message.ts
650
- var BASE_CONFIG2 = {
651
- description: __DEV__ ? "The wire format of a Solana transaction message" : "",
652
- fixedSize: null,
653
- maxSize: null
654
- };
655
- function serialize(compiledMessage) {
656
- if (compiledMessage.version === "legacy") {
657
- return umiSerializers.struct(getPreludeStructSerializerTuple()).serialize(compiledMessage);
658
- } else {
659
- return umiSerializers.mapSerializer(
660
- umiSerializers.struct([
661
- ...getPreludeStructSerializerTuple(),
662
- ["addressTableLookups", getAddressTableLookupsSerializer()]
663
- ]),
664
- (value) => {
665
- if (value.version === "legacy") {
666
- return value;
667
- }
668
- return {
669
- ...value,
670
- addressTableLookups: value.addressTableLookups ?? []
671
- };
672
- }
673
- ).serialize(compiledMessage);
674
- }
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());
675
818
  }
676
- function toSerializer(codec) {
677
- return {
678
- description: codec.description,
679
- deserialize: codec.decode,
680
- fixedSize: codec.fixedSize,
681
- maxSize: codec.maxSize,
682
- serialize: codec.encode
683
- };
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
+ );
684
835
  }
685
- function getPreludeStructSerializerTuple() {
836
+ function getPreludeStructEncoderTuple() {
686
837
  return [
687
- ["version", toSerializer(getTransactionVersionCodec())],
688
- ["header", toSerializer(getMessageHeaderCodec())],
838
+ ["version", getTransactionVersionEncoder()],
839
+ ["header", getMessageHeaderEncoder()],
689
840
  [
690
841
  "staticAccounts",
691
- umiSerializers.array(toSerializer(addresses.getAddressCodec()), {
692
- description: __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "",
693
- size: umiSerializers.shortU16()
842
+ codecsDataStructures.getArrayEncoder(addresses.getAddressEncoder(), {
843
+ description: staticAccountsDescription,
844
+ size: codecsNumbers.getShortU16Encoder()
694
845
  })
695
846
  ],
696
847
  [
697
848
  "lifetimeToken",
698
- umiSerializers.string({
699
- description: __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "",
700
- encoding: umiSerializers.base58,
849
+ codecsStrings.getStringEncoder({
850
+ description: lifetimeTokenDescription,
851
+ encoding: codecsStrings.getBase58Encoder(),
701
852
  size: 32
702
853
  })
703
854
  ],
704
855
  [
705
856
  "instructions",
706
- umiSerializers.array(getInstructionCodec(), {
707
- description: __DEV__ ? "A compact-array of instructions belonging to this transaction" : "",
708
- size: umiSerializers.shortU16()
857
+ codecsDataStructures.getArrayEncoder(getInstructionEncoder(), {
858
+ description: instructionsDescription,
859
+ size: codecsNumbers.getShortU16Encoder()
709
860
  })
710
861
  ]
711
862
  ];
712
863
  }
713
- function getAddressTableLookupsSerializer() {
714
- return umiSerializers.array(getAddressTableLookupCodec(), {
715
- ...__DEV__ ? { description: "A compact array of address table lookups belonging to this transaction" } : null,
716
- 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()
897
+ });
898
+ }
899
+ function getAddressTableLookupArrayDecoder() {
900
+ return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), {
901
+ description: addressTableLookupsDescription,
902
+ size: codecsNumbers.getShortU16Decoder()
717
903
  });
718
904
  }
905
+ var messageDescription = __DEV__ ? "The wire format of a Solana transaction message" : "message";
719
906
  function getCompiledMessageEncoder() {
720
907
  return {
721
- ...BASE_CONFIG2,
722
- deserialize: getUnimplementedDecoder("CompiledMessage"),
723
- 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
724
918
  };
725
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
+ }
726
933
 
727
934
  // src/serializers/transaction.ts
728
- var BASE_CONFIG3 = {
729
- description: __DEV__ ? "The wire format of a Solana transaction" : "",
730
- fixedSize: null,
731
- maxSize: null
732
- };
733
- function serialize2(transaction) {
734
- const compiledTransaction = getCompiledTransaction(transaction);
735
- 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(
736
939
  [
737
- "signatures",
738
- umiSerializers.array(umiSerializers.bytes({ size: 64 }), {
739
- ...__DEV__ ? { description: "A compact array of 64-byte, base-64 encoded Ed25519 signatures" } : null,
740
- size: umiSerializers.shortU16()
741
- })
940
+ [
941
+ "signatures",
942
+ codecsDataStructures.getArrayEncoder(codecsDataStructures.getBytesEncoder({ size: 64 }), {
943
+ description: signaturesDescription,
944
+ size: codecsNumbers.getShortU16Encoder()
945
+ })
946
+ ],
947
+ ["compiledMessage", getCompiledMessageEncoder()]
742
948
  ],
743
- ["compiledMessage", getCompiledMessageEncoder()]
744
- ]).serialize(compiledTransaction);
949
+ {
950
+ description: transactionDescription
951
+ }
952
+ );
745
953
  }
746
- function getTransactionEncoder() {
747
- return {
748
- ...BASE_CONFIG3,
749
- deserialize: getUnimplementedDecoder("CompiledMessage"),
750
- serialize: serialize2
751
- };
954
+ function getSignatureDecoder() {
955
+ return codecsCore.mapDecoder(codecsDataStructures.getBytesDecoder({ size: 64 }), (bytes) => bytes);
752
956
  }
753
- function assertIsTransactionSignature(putativeTransactionSignature) {
754
- try {
755
- if (
756
- // Lowest value (64 bytes of zeroes)
757
- putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
758
- putativeTransactionSignature.length > 88
759
- ) {
760
- throw new Error("Expected input string to decode to a byte array of length 64.");
761
- }
762
- const bytes3 = umiSerializers.base58.serialize(putativeTransactionSignature);
763
- const numBytes = bytes3.byteLength;
764
- if (numBytes !== 64) {
765
- throw new Error(`Expected input string to decode to a byte array of length 64. Actual length: ${numBytes}`);
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
766
971
  }
767
- } catch (e) {
768
- throw new Error(`\`${putativeTransactionSignature}\` is not a transaction signature`, {
769
- cause: e
770
- });
771
- }
972
+ );
772
973
  }
773
- function isTransactionSignature(putativeTransactionSignature) {
774
- if (
775
- // Lowest value (64 bytes of zeroes)
776
- putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
777
- putativeTransactionSignature.length > 88
778
- ) {
779
- return false;
780
- }
781
- const bytes3 = umiSerializers.base58.serialize(putativeTransactionSignature);
782
- const numBytes = bytes3.byteLength;
783
- if (numBytes !== 64) {
784
- return false;
785
- }
786
- return true;
974
+ function getTransactionEncoder() {
975
+ return codecsCore.mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
976
+ }
977
+ function getTransactionDecoder(lastValidBlockHeight) {
978
+ return codecsCore.mapDecoder(
979
+ getCompiledTransactionDecoder(),
980
+ (compiledTransaction) => decompileTransaction(compiledTransaction, lastValidBlockHeight)
981
+ );
787
982
  }
788
- async function getCompiledMessageSignature(message, secretKey) {
789
- const wireMessageBytes = getCompiledMessageEncoder().serialize(message);
790
- const signature = await keys.signBytes(secretKey, wireMessageBytes);
791
- return signature;
983
+ function getTransactionCodec(lastValidBlockHeight) {
984
+ return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
792
985
  }
986
+ var base58Decoder;
793
987
  function getSignatureFromTransaction(transaction) {
794
- const signature = transaction.signatures[transaction.feePayer];
795
- if (!signature) {
988
+ if (!base58Decoder)
989
+ base58Decoder = codecsStrings.getBase58Decoder();
990
+ const signatureBytes = transaction.signatures[transaction.feePayer];
991
+ if (!signatureBytes) {
796
992
  throw new Error(
797
993
  "Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
798
994
  );
799
995
  }
800
- return signature;
996
+ const transactionSignature = base58Decoder.decode(signatureBytes)[0];
997
+ return transactionSignature;
801
998
  }
802
- async function signTransaction(keyPairs, transaction) {
999
+ async function partiallySignTransaction(keyPairs, transaction) {
803
1000
  const compiledMessage = compileMessage(transaction);
804
1001
  const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
1002
+ const wireMessageBytes = getCompiledMessageEncoder().encode(compiledMessage);
805
1003
  const publicKeySignaturePairs = await Promise.all(
806
1004
  keyPairs.map(
807
- (keyPair) => Promise.all([
808
- addresses.getAddressFromPublicKey(keyPair.publicKey),
809
- getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
810
- ])
1005
+ (keyPair) => Promise.all([addresses.getAddressFromPublicKey(keyPair.publicKey), keys.signBytes(keyPair.privateKey, wireMessageBytes)])
811
1006
  )
812
1007
  );
813
1008
  for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
@@ -820,14 +1015,25 @@ async function signTransaction(keyPairs, transaction) {
820
1015
  Object.freeze(out);
821
1016
  return out;
822
1017
  }
823
- function transactionSignature(putativeTransactionSignature) {
824
- assertIsTransactionSignature(putativeTransactionSignature);
825
- return putativeTransactionSignature;
1018
+ async function signTransaction(keyPairs, transaction) {
1019
+ const out = await partiallySignTransaction(keyPairs, transaction);
1020
+ assertTransactionIsFullySigned(out);
1021
+ Object.freeze(out);
1022
+ return out;
1023
+ }
1024
+ function assertTransactionIsFullySigned(transaction) {
1025
+ const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
1026
+ const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
1027
+ requiredSigners.forEach((address) => {
1028
+ if (!transaction.signatures[address]) {
1029
+ throw new Error(`Transaction is missing signature for address \`${address}\``);
1030
+ }
1031
+ });
826
1032
  }
827
1033
 
828
1034
  // src/wire-transaction.ts
829
1035
  function getBase64EncodedWireTransaction(transaction) {
830
- const wireTransactionBytes = getTransactionEncoder().serialize(transaction);
1036
+ const wireTransactionBytes = getTransactionEncoder().encode(transaction);
831
1037
  {
832
1038
  return btoa(String.fromCharCode(...wireTransactionBytes));
833
1039
  }
@@ -836,17 +1042,19 @@ function getBase64EncodedWireTransaction(transaction) {
836
1042
  exports.appendTransactionInstruction = appendTransactionInstruction;
837
1043
  exports.assertIsBlockhash = assertIsBlockhash;
838
1044
  exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
839
- exports.assertIsTransactionSignature = assertIsTransactionSignature;
1045
+ exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
840
1046
  exports.createTransaction = createTransaction;
841
1047
  exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
842
1048
  exports.getSignatureFromTransaction = getSignatureFromTransaction;
1049
+ exports.getTransactionCodec = getTransactionCodec;
1050
+ exports.getTransactionDecoder = getTransactionDecoder;
843
1051
  exports.getTransactionEncoder = getTransactionEncoder;
844
- exports.isTransactionSignature = isTransactionSignature;
1052
+ exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
1053
+ exports.partiallySignTransaction = partiallySignTransaction;
845
1054
  exports.prependTransactionInstruction = prependTransactionInstruction;
846
1055
  exports.setTransactionFeePayer = setTransactionFeePayer;
847
1056
  exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
848
1057
  exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
849
1058
  exports.signTransaction = signTransaction;
850
- exports.transactionSignature = transactionSignature;
851
1059
  //# sourceMappingURL=out.js.map
852
1060
  //# sourceMappingURL=index.browser.cjs.map