@solana/transactions 2.0.0-experimental.c5061ae → 2.0.0-experimental.c7ef49c

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.
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2018 Solana Labs, Inc
1
+ Copyright (c) 2023 Solana Labs, Inc
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,6 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  var umiSerializers = require('@metaplex-foundation/umi-serializers');
4
+ var addresses = require('@solana/addresses');
5
+ var codecsDataStructures = require('@solana/codecs-data-structures');
6
+ var codecsNumbers = require('@solana/codecs-numbers');
7
+ var codecsCore = require('@solana/codecs-core');
4
8
  var keys = require('@solana/keys');
5
9
 
6
10
  // ../build-scripts/env-shim.ts
@@ -96,6 +100,20 @@ function assertIsDurableNonceTransaction(transaction) {
96
100
  throw new Error("Transaction is not a durable nonce transaction");
97
101
  }
98
102
  }
103
+ function createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress) {
104
+ return {
105
+ accounts: [
106
+ { address: nonceAccountAddress, role: AccountRole.WRITABLE },
107
+ {
108
+ address: RECENT_BLOCKHASHES_SYSVAR_ADDRESS,
109
+ role: AccountRole.READONLY
110
+ },
111
+ { address: nonceAuthorityAddress, role: AccountRole.READONLY_SIGNER }
112
+ ],
113
+ data: new Uint8Array([4, 0, 0, 0]),
114
+ programAddress: SYSTEM_PROGRAM_ADDRESS
115
+ };
116
+ }
99
117
  function isAdvanceNonceAccountInstruction(instruction) {
100
118
  return instruction.programAddress === SYSTEM_PROGRAM_ADDRESS && // Test for `AdvanceNonceAccount` instruction data
101
119
  instruction.data != null && isAdvanceNonceAccountInstructionData(instruction.data) && // Test for exactly 3 accounts
@@ -110,6 +128,28 @@ function isAdvanceNonceAccountInstructionData(data) {
110
128
  function isDurableNonceTransaction(transaction) {
111
129
  return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
112
130
  }
131
+ function setTransactionLifetimeUsingDurableNonce({
132
+ nonce,
133
+ nonceAccountAddress,
134
+ nonceAuthorityAddress
135
+ }, 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;
139
+ }
140
+ const out = {
141
+ ...getUnsignedTransaction(transaction),
142
+ instructions: [
143
+ createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
144
+ ...isAlreadyDurableNonceTransaction ? transaction.instructions.slice(1) : transaction.instructions
145
+ ],
146
+ lifetimeConstraint: {
147
+ nonce
148
+ }
149
+ };
150
+ Object.freeze(out);
151
+ return out;
152
+ }
113
153
 
114
154
  // src/fee-payer.ts
115
155
  function setTransactionFeePayer(feePayer, transaction) {
@@ -193,7 +233,7 @@ function getAddressMapFromInstructions(feePayer, instructions) {
193
233
  const shouldReplaceEntry = (
194
234
  // Consider using the new LOOKUP_TABLE if its address is different...
195
235
  entry.lookupTableAddress !== accountMeta.lookupTableAddress && // ...and sorts before the existing one.
196
- (addressComparator || (addressComparator = keys.getBase58EncodedAddressComparator()))(
236
+ (addressComparator || (addressComparator = addresses.getAddressComparator()))(
197
237
  accountMeta.lookupTableAddress,
198
238
  entry.lookupTableAddress
199
239
  ) < 0
@@ -299,7 +339,7 @@ function getOrderedAccountsFromAddressMap(addressMap) {
299
339
  if (leftIsWritable !== isWritableRole(rightEntry.role)) {
300
340
  return leftIsWritable ? -1 : 1;
301
341
  }
302
- addressComparator || (addressComparator = keys.getBase58EncodedAddressComparator());
342
+ addressComparator || (addressComparator = addresses.getAddressComparator());
303
343
  if (leftEntry[TYPE] === 1 /* LOOKUP_TABLE */ && rightEntry[TYPE] === 1 /* LOOKUP_TABLE */ && leftEntry.lookupTableAddress !== rightEntry.lookupTableAddress) {
304
344
  return addressComparator(leftEntry.lookupTableAddress, rightEntry.lookupTableAddress);
305
345
  } else {
@@ -328,7 +368,7 @@ function getCompiledAddressTableLookups(orderedAccounts) {
328
368
  entry.readableIndices.push(account.addressIndex);
329
369
  }
330
370
  }
331
- return Object.keys(index).sort(keys.getBase58EncodedAddressComparator()).map((lookupTableAddress) => ({
371
+ return Object.keys(index).sort(addresses.getAddressComparator()).map((lookupTableAddress) => ({
332
372
  lookupTableAddress,
333
373
  ...index[lookupTableAddress]
334
374
  }));
@@ -407,12 +447,40 @@ function compileMessage(transaction) {
407
447
  version: transaction.version
408
448
  };
409
449
  }
450
+
451
+ // src/compile-transaction.ts
452
+ function getCompiledTransaction(transaction) {
453
+ const compiledMessage = compileMessage(transaction);
454
+ let signatures;
455
+ if ("signatures" in transaction) {
456
+ signatures = [];
457
+ for (let ii = 0; ii < compiledMessage.header.numSignerAccounts; ii++) {
458
+ signatures[ii] = transaction.signatures[compiledMessage.staticAccounts[ii]] ?? new Uint8Array(Array(64).fill(0));
459
+ }
460
+ } else {
461
+ signatures = Array(compiledMessage.header.numSignerAccounts).fill(new Uint8Array(Array(64).fill(0)));
462
+ }
463
+ return {
464
+ compiledMessage,
465
+ signatures
466
+ };
467
+ }
468
+ function addressSerializerCompat(compat) {
469
+ const codec = addresses.getAddressCodec();
470
+ return {
471
+ description: compat?.description ?? codec.description,
472
+ deserialize: codec.decode,
473
+ fixedSize: codec.fixedSize,
474
+ maxSize: codec.maxSize,
475
+ serialize: codec.encode
476
+ };
477
+ }
410
478
  function getAddressTableLookupCodec() {
411
479
  return umiSerializers.struct(
412
480
  [
413
481
  [
414
482
  "lookupTableAddress",
415
- keys.getBase58EncodedAddressCodec(
483
+ addressSerializerCompat(
416
484
  __DEV__ ? {
417
485
  description: "The address of the address lookup table account from which instruction addresses should be looked up"
418
486
  } : void 0
@@ -442,37 +510,33 @@ function getAddressTableLookupCodec() {
442
510
  } : void 0
443
511
  );
444
512
  }
513
+ var memoizedU8Codec;
514
+ function getMemoizedU8Codec() {
515
+ if (!memoizedU8Codec)
516
+ memoizedU8Codec = codecsNumbers.getU8Codec();
517
+ return memoizedU8Codec;
518
+ }
519
+ function getMemoizedU8CodecDescription(description) {
520
+ const codec = getMemoizedU8Codec();
521
+ return {
522
+ ...codec,
523
+ description: description ?? codec.description
524
+ };
525
+ }
526
+ 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
+ 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
+ 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
+ var messageHeaderDescription = __DEV__ ? "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses" : void 0;
445
530
  function getMessageHeaderCodec() {
446
- return umiSerializers.struct(
531
+ return codecsDataStructures.getStructCodec(
447
532
  [
448
- [
449
- "numSignerAccounts",
450
- umiSerializers.u8(
451
- __DEV__ ? {
452
- description: "The expected number of addresses in the static address list belonging to accounts that are required to sign this transaction"
453
- } : void 0
454
- )
455
- ],
456
- [
457
- "numReadonlySignerAccounts",
458
- umiSerializers.u8(
459
- __DEV__ ? {
460
- description: "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"
461
- } : void 0
462
- )
463
- ],
464
- [
465
- "numReadonlyNonSignerAccounts",
466
- umiSerializers.u8(
467
- __DEV__ ? {
468
- description: "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable"
469
- } : void 0
470
- )
471
- ]
533
+ ["numSignerAccounts", getMemoizedU8CodecDescription(numSignerAccountsDescription)],
534
+ ["numReadonlySignerAccounts", getMemoizedU8CodecDescription(numReadonlySignerAccountsDescription)],
535
+ ["numReadonlyNonSignerAccounts", getMemoizedU8CodecDescription(numReadonlyNonSignerAccountsDescription)]
472
536
  ],
473
- __DEV__ ? {
474
- description: "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses"
475
- } : void 0
537
+ {
538
+ description: messageHeaderDescription
539
+ }
476
540
  );
477
541
  }
478
542
  function getInstructionCodec() {
@@ -487,7 +551,7 @@ function getInstructionCodec() {
487
551
  )
488
552
  ],
489
553
  [
490
- "addressIndices",
554
+ "accountIndices",
491
555
  umiSerializers.array(
492
556
  umiSerializers.u8({
493
557
  description: __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : ""
@@ -507,50 +571,35 @@ function getInstructionCodec() {
507
571
  ]
508
572
  ]),
509
573
  (value) => {
510
- if (value.addressIndices !== void 0 && value.data !== void 0) {
574
+ if (value.accountIndices !== void 0 && value.data !== void 0) {
511
575
  return value;
512
576
  }
513
577
  return {
514
578
  ...value,
515
- addressIndices: value.addressIndices ?? [],
579
+ accountIndices: value.accountIndices ?? [],
516
580
  data: value.data ?? new Uint8Array(0)
517
581
  };
518
582
  },
519
583
  (value) => {
520
- if (value.addressIndices.length && value.data.byteLength) {
584
+ if (value.accountIndices.length && value.data.byteLength) {
521
585
  return value;
522
586
  }
523
- const { addressIndices, data, ...rest } = value;
587
+ const { accountIndices, data, ...rest } = value;
524
588
  return {
525
589
  ...rest,
526
- ...addressIndices.length ? { addressIndices } : null,
590
+ ...accountIndices.length ? { accountIndices } : null,
527
591
  ...data.byteLength ? { data } : null
528
592
  };
529
593
  }
530
594
  );
531
595
  }
532
-
533
- // src/serializers/unimplemented.ts
534
- function getError(type, name) {
535
- const functionSuffix = name + type[0].toUpperCase() + type.slice(1);
536
- return new Error(
537
- `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}`
538
- );
539
- }
540
- function getUnimplementedDecoder(name) {
541
- return () => {
542
- throw getError("decoder", name);
543
- };
544
- }
545
-
546
- // src/serializers/transaction-version.ts
547
596
  var VERSION_FLAG_MASK = 128;
548
597
  var BASE_CONFIG = {
549
598
  description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
550
599
  fixedSize: null,
551
600
  maxSize: 1
552
601
  };
553
- function deserialize(bytes3, offset = 0) {
602
+ function decode(bytes3, offset = 0) {
554
603
  const firstByte = bytes3[offset];
555
604
  if ((firstByte & VERSION_FLAG_MASK) === 0) {
556
605
  return ["legacy", offset];
@@ -559,7 +608,7 @@ function deserialize(bytes3, offset = 0) {
559
608
  return [version, offset + 1];
560
609
  }
561
610
  }
562
- function serialize(value) {
611
+ function encode(value) {
563
612
  if (value === "legacy") {
564
613
  return new Uint8Array();
565
614
  }
@@ -568,11 +617,32 @@ function serialize(value) {
568
617
  }
569
618
  return new Uint8Array([value | VERSION_FLAG_MASK]);
570
619
  }
571
- function getTransactionVersionCodec() {
620
+ function getTransactionVersionDecoder() {
572
621
  return {
573
622
  ...BASE_CONFIG,
574
- deserialize,
575
- serialize
623
+ decode
624
+ };
625
+ }
626
+ function getTransactionVersionEncoder() {
627
+ return {
628
+ ...BASE_CONFIG,
629
+ encode
630
+ };
631
+ }
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);
576
646
  };
577
647
  }
578
648
 
@@ -582,7 +652,7 @@ var BASE_CONFIG2 = {
582
652
  fixedSize: null,
583
653
  maxSize: null
584
654
  };
585
- function serialize2(compiledMessage) {
655
+ function serialize(compiledMessage) {
586
656
  if (compiledMessage.version === "legacy") {
587
657
  return umiSerializers.struct(getPreludeStructSerializerTuple()).serialize(compiledMessage);
588
658
  } else {
@@ -603,13 +673,22 @@ function serialize2(compiledMessage) {
603
673
  ).serialize(compiledMessage);
604
674
  }
605
675
  }
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
+ };
684
+ }
606
685
  function getPreludeStructSerializerTuple() {
607
686
  return [
608
- ["version", getTransactionVersionCodec()],
609
- ["header", getMessageHeaderCodec()],
687
+ ["version", toSerializer(getTransactionVersionCodec())],
688
+ ["header", toSerializer(getMessageHeaderCodec())],
610
689
  [
611
690
  "staticAccounts",
612
- umiSerializers.array(keys.getBase58EncodedAddressCodec(), {
691
+ umiSerializers.array(toSerializer(addresses.getAddressCodec()), {
613
692
  description: __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "",
614
693
  size: umiSerializers.shortU16()
615
694
  })
@@ -641,49 +720,7 @@ function getCompiledMessageEncoder() {
641
720
  return {
642
721
  ...BASE_CONFIG2,
643
722
  deserialize: getUnimplementedDecoder("CompiledMessage"),
644
- serialize: serialize2
645
- };
646
- }
647
-
648
- // src/signatures.ts
649
- async function getCompiledMessageSignature(message, secretKey) {
650
- const wireMessageBytes = getCompiledMessageEncoder().serialize(message);
651
- const signature = await keys.signBytes(secretKey, wireMessageBytes);
652
- return signature;
653
- }
654
- async function signTransaction(keyPair, transaction) {
655
- const compiledMessage = compileMessage(transaction);
656
- const [signerPublicKey, signature] = await Promise.all([
657
- keys.getBase58EncodedAddressFromPublicKey(keyPair.publicKey),
658
- getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
659
- ]);
660
- const nextSignatures = {
661
- ..."signatures" in transaction ? transaction.signatures : null,
662
- ...{ [signerPublicKey]: signature }
663
- };
664
- const out = {
665
- ...transaction,
666
- signatures: nextSignatures
667
- };
668
- Object.freeze(out);
669
- return out;
670
- }
671
-
672
- // src/compile-transaction.ts
673
- function getCompiledTransaction(transaction) {
674
- const compiledMessage = compileMessage(transaction);
675
- let signatures;
676
- if ("signatures" in transaction) {
677
- signatures = [];
678
- for (let ii = 0; ii < compiledMessage.header.numSignerAccounts; ii++) {
679
- signatures[ii] = transaction.signatures[compiledMessage.staticAccounts[ii]] ?? new Uint8Array(Array(64).fill(0));
680
- }
681
- } else {
682
- signatures = Array(compiledMessage.header.numSignerAccounts).fill(new Uint8Array(Array(64).fill(0)));
683
- }
684
- return {
685
- compiledMessage,
686
- signatures
723
+ serialize
687
724
  };
688
725
  }
689
726
 
@@ -693,7 +730,7 @@ var BASE_CONFIG3 = {
693
730
  fixedSize: null,
694
731
  maxSize: null
695
732
  };
696
- function serialize3(transaction) {
733
+ function serialize2(transaction) {
697
734
  const compiledTransaction = getCompiledTransaction(transaction);
698
735
  return umiSerializers.struct([
699
736
  [
@@ -710,8 +747,82 @@ function getTransactionEncoder() {
710
747
  return {
711
748
  ...BASE_CONFIG3,
712
749
  deserialize: getUnimplementedDecoder("CompiledMessage"),
713
- serialize: serialize3
750
+ serialize: serialize2
751
+ };
752
+ }
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}`);
766
+ }
767
+ } catch (e) {
768
+ throw new Error(`\`${putativeTransactionSignature}\` is not a transaction signature`, {
769
+ cause: e
770
+ });
771
+ }
772
+ }
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;
787
+ }
788
+ async function getCompiledMessageSignature(message, secretKey) {
789
+ const wireMessageBytes = getCompiledMessageEncoder().serialize(message);
790
+ const signature = await keys.signBytes(secretKey, wireMessageBytes);
791
+ return signature;
792
+ }
793
+ function getSignatureFromTransaction(transaction) {
794
+ const signature = transaction.signatures[transaction.feePayer];
795
+ if (!signature) {
796
+ throw new Error(
797
+ "Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
798
+ );
799
+ }
800
+ return signature;
801
+ }
802
+ async function signTransaction(keyPairs, transaction) {
803
+ const compiledMessage = compileMessage(transaction);
804
+ const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
805
+ const publicKeySignaturePairs = await Promise.all(
806
+ keyPairs.map(
807
+ (keyPair) => Promise.all([
808
+ addresses.getAddressFromPublicKey(keyPair.publicKey),
809
+ getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
810
+ ])
811
+ )
812
+ );
813
+ for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
814
+ nextSignatures[signerPublicKey] = signature;
815
+ }
816
+ const out = {
817
+ ...transaction,
818
+ signatures: nextSignatures
714
819
  };
820
+ Object.freeze(out);
821
+ return out;
822
+ }
823
+ function transactionSignature(putativeTransactionSignature) {
824
+ assertIsTransactionSignature(putativeTransactionSignature);
825
+ return putativeTransactionSignature;
715
826
  }
716
827
 
717
828
  // src/wire-transaction.ts
@@ -725,9 +836,17 @@ function getBase64EncodedWireTransaction(transaction) {
725
836
  exports.appendTransactionInstruction = appendTransactionInstruction;
726
837
  exports.assertIsBlockhash = assertIsBlockhash;
727
838
  exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
839
+ exports.assertIsTransactionSignature = assertIsTransactionSignature;
728
840
  exports.createTransaction = createTransaction;
729
841
  exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
842
+ exports.getSignatureFromTransaction = getSignatureFromTransaction;
843
+ exports.getTransactionEncoder = getTransactionEncoder;
844
+ exports.isTransactionSignature = isTransactionSignature;
730
845
  exports.prependTransactionInstruction = prependTransactionInstruction;
731
846
  exports.setTransactionFeePayer = setTransactionFeePayer;
732
847
  exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
848
+ exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
733
849
  exports.signTransaction = signTransaction;
850
+ exports.transactionSignature = transactionSignature;
851
+ //# sourceMappingURL=out.js.map
852
+ //# sourceMappingURL=index.browser.cjs.map