@solana/transactions 2.0.0-experimental.71b920d → 2.0.0-experimental.72efece

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,77 +1,68 @@
1
- import { getBase58EncodedAddressFromPublicKey, signBytes, getBase58EncodedAddressComparator, getBase58EncodedAddressCodec } from '@solana/keys';
2
- import { struct, mapSerializer, array, shortU16, string, base58, u8, bytes } from '@metaplex-foundation/umi-serializers';
1
+ import { base58, struct, array, bytes, shortU16, mapSerializer, string, u8 } from '@metaplex-foundation/umi-serializers';
2
+ import { getAddressFromPublicKey, getAddressComparator, getAddressCodec } from '@solana/addresses';
3
+ import { getStructCodec } from '@solana/codecs-data-structures';
4
+ import { getU8Codec } from '@solana/codecs-numbers';
5
+ import { combineCodec } from '@solana/codecs-core';
6
+ import { signBytes } from '@solana/keys';
3
7
 
4
8
  // ../build-scripts/env-shim.ts
5
9
  var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
6
10
 
7
- // src/create-transaction.ts
8
- function createTransaction({
9
- version
10
- }) {
11
- const out = {
12
- instructions: [],
13
- version
14
- };
15
- Object.freeze(out);
16
- return out;
17
- }
18
-
19
- // src/fee-payer.ts
20
- function setTransactionFeePayer(feePayer, transaction) {
21
- if ("feePayer" in transaction && feePayer === transaction.feePayer) {
22
- return transaction;
23
- }
24
- let out;
11
+ // src/unsigned-transaction.ts
12
+ function getUnsignedTransaction(transaction) {
25
13
  if ("signatures" in transaction) {
26
14
  const {
27
15
  signatures: _,
28
16
  // eslint-disable-line @typescript-eslint/no-unused-vars
29
17
  ...unsignedTransaction
30
18
  } = transaction;
31
- out = {
32
- ...unsignedTransaction,
33
- feePayer
34
- };
19
+ return unsignedTransaction;
35
20
  } else {
36
- out = {
37
- ...transaction,
38
- feePayer
39
- };
21
+ return transaction;
40
22
  }
41
- Object.freeze(out);
42
- return out;
43
23
  }
44
24
 
45
- // src/instructions.ts
46
- function replaceInstructions(transaction, nextInstructions) {
47
- let out;
48
- if ("signatures" in transaction) {
49
- const {
50
- signatures: _,
51
- // eslint-disable-line @typescript-eslint/no-unused-vars
52
- ...unsignedTransaction
53
- } = transaction;
54
- out = {
55
- ...unsignedTransaction,
56
- instructions: nextInstructions
57
- };
58
- } else {
59
- out = {
60
- ...transaction,
61
- instructions: nextInstructions
62
- };
25
+ // src/blockhash.ts
26
+ function assertIsBlockhash(putativeBlockhash) {
27
+ try {
28
+ if (
29
+ // Lowest value (32 bytes of zeroes)
30
+ putativeBlockhash.length < 32 || // Highest value (32 bytes of 255)
31
+ putativeBlockhash.length > 44
32
+ ) {
33
+ throw new Error("Expected input string to decode to a byte array of length 32.");
34
+ }
35
+ const bytes3 = base58.serialize(putativeBlockhash);
36
+ const numBytes = bytes3.byteLength;
37
+ if (numBytes !== 32) {
38
+ throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
39
+ }
40
+ } catch (e) {
41
+ throw new Error(`\`${putativeBlockhash}\` is not a blockhash`, {
42
+ cause: e
43
+ });
63
44
  }
64
- return out;
65
45
  }
66
- function appendTransactionInstruction(instruction, transaction) {
67
- const nextInstructions = [...transaction.instructions, instruction];
68
- const out = replaceInstructions(transaction, nextInstructions);
46
+ function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
47
+ if ("lifetimeConstraint" in transaction && transaction.lifetimeConstraint.blockhash === blockhashLifetimeConstraint.blockhash && transaction.lifetimeConstraint.lastValidBlockHeight === blockhashLifetimeConstraint.lastValidBlockHeight) {
48
+ return transaction;
49
+ }
50
+ const out = {
51
+ ...getUnsignedTransaction(transaction),
52
+ lifetimeConstraint: blockhashLifetimeConstraint
53
+ };
69
54
  Object.freeze(out);
70
55
  return out;
71
56
  }
72
- function prependTransactionInstruction(instruction, transaction) {
73
- const nextInstructions = [instruction, ...transaction.instructions];
74
- const out = replaceInstructions(transaction, nextInstructions);
57
+
58
+ // src/create-transaction.ts
59
+ function createTransaction({
60
+ version
61
+ }) {
62
+ const out = {
63
+ instructions: [],
64
+ version
65
+ };
75
66
  Object.freeze(out);
76
67
  return out;
77
68
  }
@@ -98,6 +89,96 @@ function isWritableRole(role) {
98
89
  function mergeRoles(roleA, roleB) {
99
90
  return roleA | roleB;
100
91
  }
92
+
93
+ // src/durable-nonce.ts
94
+ var RECENT_BLOCKHASHES_SYSVAR_ADDRESS = "SysvarRecentB1ockHashes11111111111111111111";
95
+ var SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
96
+ function assertIsDurableNonceTransaction(transaction) {
97
+ if (!isDurableNonceTransaction(transaction)) {
98
+ throw new Error("Transaction is not a durable nonce transaction");
99
+ }
100
+ }
101
+ function createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress) {
102
+ return {
103
+ accounts: [
104
+ { address: nonceAccountAddress, role: AccountRole.WRITABLE },
105
+ {
106
+ address: RECENT_BLOCKHASHES_SYSVAR_ADDRESS,
107
+ role: AccountRole.READONLY
108
+ },
109
+ { address: nonceAuthorityAddress, role: AccountRole.READONLY_SIGNER }
110
+ ],
111
+ data: new Uint8Array([4, 0, 0, 0]),
112
+ programAddress: SYSTEM_PROGRAM_ADDRESS
113
+ };
114
+ }
115
+ function isAdvanceNonceAccountInstruction(instruction) {
116
+ return instruction.programAddress === SYSTEM_PROGRAM_ADDRESS && // Test for `AdvanceNonceAccount` instruction data
117
+ instruction.data != null && isAdvanceNonceAccountInstructionData(instruction.data) && // Test for exactly 3 accounts
118
+ instruction.accounts?.length === 3 && // First account is nonce account address
119
+ instruction.accounts[0].address != null && instruction.accounts[0].role === AccountRole.WRITABLE && // Second account is recent blockhashes sysvar
120
+ instruction.accounts[1].address === RECENT_BLOCKHASHES_SYSVAR_ADDRESS && instruction.accounts[1].role === AccountRole.READONLY && // Third account is nonce authority account
121
+ instruction.accounts[2].address != null && instruction.accounts[2].role === AccountRole.READONLY_SIGNER;
122
+ }
123
+ function isAdvanceNonceAccountInstructionData(data) {
124
+ return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;
125
+ }
126
+ function isDurableNonceTransaction(transaction) {
127
+ return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
128
+ }
129
+ function setTransactionLifetimeUsingDurableNonce({
130
+ nonce,
131
+ nonceAccountAddress,
132
+ nonceAuthorityAddress
133
+ }, transaction) {
134
+ const isAlreadyDurableNonceTransaction = isDurableNonceTransaction(transaction);
135
+ if (isAlreadyDurableNonceTransaction && transaction.lifetimeConstraint.nonce === nonce && transaction.instructions[0].accounts[0].address === nonceAccountAddress && transaction.instructions[0].accounts[2].address === nonceAuthorityAddress) {
136
+ return transaction;
137
+ }
138
+ const out = {
139
+ ...getUnsignedTransaction(transaction),
140
+ instructions: [
141
+ createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
142
+ ...isAlreadyDurableNonceTransaction ? transaction.instructions.slice(1) : transaction.instructions
143
+ ],
144
+ lifetimeConstraint: {
145
+ nonce
146
+ }
147
+ };
148
+ Object.freeze(out);
149
+ return out;
150
+ }
151
+
152
+ // src/fee-payer.ts
153
+ function setTransactionFeePayer(feePayer, transaction) {
154
+ if ("feePayer" in transaction && feePayer === transaction.feePayer) {
155
+ return transaction;
156
+ }
157
+ const out = {
158
+ ...getUnsignedTransaction(transaction),
159
+ feePayer
160
+ };
161
+ Object.freeze(out);
162
+ return out;
163
+ }
164
+
165
+ // src/instructions.ts
166
+ function appendTransactionInstruction(instruction, transaction) {
167
+ const out = {
168
+ ...getUnsignedTransaction(transaction),
169
+ instructions: [...transaction.instructions, instruction]
170
+ };
171
+ Object.freeze(out);
172
+ return out;
173
+ }
174
+ function prependTransactionInstruction(instruction, transaction) {
175
+ const out = {
176
+ ...getUnsignedTransaction(transaction),
177
+ instructions: [instruction, ...transaction.instructions]
178
+ };
179
+ Object.freeze(out);
180
+ return out;
181
+ }
101
182
  function upsert(addressMap, address, update) {
102
183
  addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
103
184
  }
@@ -150,7 +231,7 @@ function getAddressMapFromInstructions(feePayer, instructions) {
150
231
  const shouldReplaceEntry = (
151
232
  // Consider using the new LOOKUP_TABLE if its address is different...
152
233
  entry.lookupTableAddress !== accountMeta.lookupTableAddress && // ...and sorts before the existing one.
153
- (addressComparator || (addressComparator = getBase58EncodedAddressComparator()))(
234
+ (addressComparator || (addressComparator = getAddressComparator()))(
154
235
  accountMeta.lookupTableAddress,
155
236
  entry.lookupTableAddress
156
237
  ) < 0
@@ -256,7 +337,7 @@ function getOrderedAccountsFromAddressMap(addressMap) {
256
337
  if (leftIsWritable !== isWritableRole(rightEntry.role)) {
257
338
  return leftIsWritable ? -1 : 1;
258
339
  }
259
- addressComparator || (addressComparator = getBase58EncodedAddressComparator());
340
+ addressComparator || (addressComparator = getAddressComparator());
260
341
  if (leftEntry[TYPE] === 1 /* LOOKUP_TABLE */ && rightEntry[TYPE] === 1 /* LOOKUP_TABLE */ && leftEntry.lookupTableAddress !== rightEntry.lookupTableAddress) {
261
342
  return addressComparator(leftEntry.lookupTableAddress, rightEntry.lookupTableAddress);
262
343
  } else {
@@ -285,7 +366,7 @@ function getCompiledAddressTableLookups(orderedAccounts) {
285
366
  entry.readableIndices.push(account.addressIndex);
286
367
  }
287
368
  }
288
- return Object.keys(index).sort(getBase58EncodedAddressComparator()).map((lookupTableAddress) => ({
369
+ return Object.keys(index).sort(getAddressComparator()).map((lookupTableAddress) => ({
289
370
  lookupTableAddress,
290
371
  ...index[lookupTableAddress]
291
372
  }));
@@ -364,12 +445,40 @@ function compileMessage(transaction) {
364
445
  version: transaction.version
365
446
  };
366
447
  }
448
+
449
+ // src/compile-transaction.ts
450
+ function getCompiledTransaction(transaction) {
451
+ const compiledMessage = compileMessage(transaction);
452
+ let signatures;
453
+ if ("signatures" in transaction) {
454
+ signatures = [];
455
+ for (let ii = 0; ii < compiledMessage.header.numSignerAccounts; ii++) {
456
+ signatures[ii] = transaction.signatures[compiledMessage.staticAccounts[ii]] ?? new Uint8Array(Array(64).fill(0));
457
+ }
458
+ } else {
459
+ signatures = Array(compiledMessage.header.numSignerAccounts).fill(new Uint8Array(Array(64).fill(0)));
460
+ }
461
+ return {
462
+ compiledMessage,
463
+ signatures
464
+ };
465
+ }
466
+ function addressSerializerCompat(compat) {
467
+ const codec = getAddressCodec();
468
+ return {
469
+ description: compat?.description ?? codec.description,
470
+ deserialize: codec.decode,
471
+ fixedSize: codec.fixedSize,
472
+ maxSize: codec.maxSize,
473
+ serialize: codec.encode
474
+ };
475
+ }
367
476
  function getAddressTableLookupCodec() {
368
477
  return struct(
369
478
  [
370
479
  [
371
480
  "lookupTableAddress",
372
- getBase58EncodedAddressCodec(
481
+ addressSerializerCompat(
373
482
  __DEV__ ? {
374
483
  description: "The address of the address lookup table account from which instruction addresses should be looked up"
375
484
  } : void 0
@@ -399,37 +508,33 @@ function getAddressTableLookupCodec() {
399
508
  } : void 0
400
509
  );
401
510
  }
511
+ var memoizedU8Codec;
512
+ function getMemoizedU8Codec() {
513
+ if (!memoizedU8Codec)
514
+ memoizedU8Codec = getU8Codec();
515
+ return memoizedU8Codec;
516
+ }
517
+ function getMemoizedU8CodecDescription(description) {
518
+ const codec = getMemoizedU8Codec();
519
+ return {
520
+ ...codec,
521
+ description: description ?? codec.description
522
+ };
523
+ }
524
+ 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;
525
+ 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;
526
+ var numReadonlyNonSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable" : void 0;
527
+ var messageHeaderDescription = __DEV__ ? "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses" : void 0;
402
528
  function getMessageHeaderCodec() {
403
- return struct(
529
+ return getStructCodec(
404
530
  [
405
- [
406
- "numSignerAccounts",
407
- u8(
408
- __DEV__ ? {
409
- description: "The expected number of addresses in the static address list belonging to accounts that are required to sign this transaction"
410
- } : void 0
411
- )
412
- ],
413
- [
414
- "numReadonlySignerAccounts",
415
- u8(
416
- __DEV__ ? {
417
- 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"
418
- } : void 0
419
- )
420
- ],
421
- [
422
- "numReadonlyNonSignerAccounts",
423
- u8(
424
- __DEV__ ? {
425
- description: "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable"
426
- } : void 0
427
- )
428
- ]
531
+ ["numSignerAccounts", getMemoizedU8CodecDescription(numSignerAccountsDescription)],
532
+ ["numReadonlySignerAccounts", getMemoizedU8CodecDescription(numReadonlySignerAccountsDescription)],
533
+ ["numReadonlyNonSignerAccounts", getMemoizedU8CodecDescription(numReadonlyNonSignerAccountsDescription)]
429
534
  ],
430
- __DEV__ ? {
431
- description: "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses"
432
- } : void 0
535
+ {
536
+ description: messageHeaderDescription
537
+ }
433
538
  );
434
539
  }
435
540
  function getInstructionCodec() {
@@ -444,7 +549,7 @@ function getInstructionCodec() {
444
549
  )
445
550
  ],
446
551
  [
447
- "addressIndices",
552
+ "accountIndices",
448
553
  array(
449
554
  u8({
450
555
  description: __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : ""
@@ -464,51 +569,36 @@ function getInstructionCodec() {
464
569
  ]
465
570
  ]),
466
571
  (value) => {
467
- if (value.addressIndices !== void 0 && value.data !== void 0) {
572
+ if (value.accountIndices !== void 0 && value.data !== void 0) {
468
573
  return value;
469
574
  }
470
575
  return {
471
576
  ...value,
472
- addressIndices: value.addressIndices ?? [],
577
+ accountIndices: value.accountIndices ?? [],
473
578
  data: value.data ?? new Uint8Array(0)
474
579
  };
475
580
  },
476
581
  (value) => {
477
- if (value.addressIndices.length && value.data.byteLength) {
582
+ if (value.accountIndices.length && value.data.byteLength) {
478
583
  return value;
479
584
  }
480
- const { addressIndices, data, ...rest } = value;
585
+ const { accountIndices, data, ...rest } = value;
481
586
  return {
482
587
  ...rest,
483
- ...addressIndices.length ? { addressIndices } : null,
588
+ ...accountIndices.length ? { accountIndices } : null,
484
589
  ...data.byteLength ? { data } : null
485
590
  };
486
591
  }
487
592
  );
488
593
  }
489
-
490
- // src/serializers/unimplemented.ts
491
- function getError(type, name) {
492
- const functionSuffix = name + type[0].toUpperCase() + type.slice(1);
493
- return new Error(
494
- `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}`
495
- );
496
- }
497
- function getUnimplementedDecoder(name) {
498
- return () => {
499
- throw getError("decoder", name);
500
- };
501
- }
502
-
503
- // src/serializers/transaction-version.ts
504
594
  var VERSION_FLAG_MASK = 128;
505
595
  var BASE_CONFIG = {
506
596
  description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
507
597
  fixedSize: null,
508
598
  maxSize: 1
509
599
  };
510
- function deserialize(bytes2, offset = 0) {
511
- const firstByte = bytes2[offset];
600
+ function decode(bytes3, offset = 0) {
601
+ const firstByte = bytes3[offset];
512
602
  if ((firstByte & VERSION_FLAG_MASK) === 0) {
513
603
  return ["legacy", offset];
514
604
  } else {
@@ -516,7 +606,7 @@ function deserialize(bytes2, offset = 0) {
516
606
  return [version, offset + 1];
517
607
  }
518
608
  }
519
- function serialize(value) {
609
+ function encode(value) {
520
610
  if (value === "legacy") {
521
611
  return new Uint8Array();
522
612
  }
@@ -525,11 +615,32 @@ function serialize(value) {
525
615
  }
526
616
  return new Uint8Array([value | VERSION_FLAG_MASK]);
527
617
  }
528
- function getTransactionVersionCodec() {
618
+ function getTransactionVersionDecoder() {
529
619
  return {
530
620
  ...BASE_CONFIG,
531
- deserialize,
532
- serialize
621
+ decode
622
+ };
623
+ }
624
+ function getTransactionVersionEncoder() {
625
+ return {
626
+ ...BASE_CONFIG,
627
+ encode
628
+ };
629
+ }
630
+ function getTransactionVersionCodec() {
631
+ return combineCodec(getTransactionVersionEncoder(), getTransactionVersionDecoder());
632
+ }
633
+
634
+ // src/serializers/unimplemented.ts
635
+ function getError(type, name) {
636
+ const functionSuffix = name + type[0].toUpperCase() + type.slice(1);
637
+ return new Error(
638
+ `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}`
639
+ );
640
+ }
641
+ function getUnimplementedDecoder(name) {
642
+ return () => {
643
+ throw getError("decoder", name);
533
644
  };
534
645
  }
535
646
 
@@ -539,7 +650,7 @@ var BASE_CONFIG2 = {
539
650
  fixedSize: null,
540
651
  maxSize: null
541
652
  };
542
- function serialize2(compiledMessage) {
653
+ function serialize(compiledMessage) {
543
654
  if (compiledMessage.version === "legacy") {
544
655
  return struct(getPreludeStructSerializerTuple()).serialize(compiledMessage);
545
656
  } else {
@@ -560,13 +671,22 @@ function serialize2(compiledMessage) {
560
671
  ).serialize(compiledMessage);
561
672
  }
562
673
  }
674
+ function toSerializer(codec) {
675
+ return {
676
+ description: codec.description,
677
+ deserialize: codec.decode,
678
+ fixedSize: codec.fixedSize,
679
+ maxSize: codec.maxSize,
680
+ serialize: codec.encode
681
+ };
682
+ }
563
683
  function getPreludeStructSerializerTuple() {
564
684
  return [
565
- ["version", getTransactionVersionCodec()],
566
- ["header", getMessageHeaderCodec()],
685
+ ["version", toSerializer(getTransactionVersionCodec())],
686
+ ["header", toSerializer(getMessageHeaderCodec())],
567
687
  [
568
688
  "staticAccounts",
569
- array(getBase58EncodedAddressCodec(), {
689
+ array(toSerializer(getAddressCodec()), {
570
690
  description: __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "",
571
691
  size: shortU16()
572
692
  })
@@ -598,26 +718,99 @@ function getCompiledMessageEncoder() {
598
718
  return {
599
719
  ...BASE_CONFIG2,
600
720
  deserialize: getUnimplementedDecoder("CompiledMessage"),
601
- serialize: serialize2
721
+ serialize
602
722
  };
603
723
  }
604
724
 
605
- // src/signatures.ts
725
+ // src/serializers/transaction.ts
726
+ var BASE_CONFIG3 = {
727
+ description: __DEV__ ? "The wire format of a Solana transaction" : "",
728
+ fixedSize: null,
729
+ maxSize: null
730
+ };
731
+ function serialize2(transaction) {
732
+ const compiledTransaction = getCompiledTransaction(transaction);
733
+ return struct([
734
+ [
735
+ "signatures",
736
+ array(bytes({ size: 64 }), {
737
+ ...__DEV__ ? { description: "A compact array of 64-byte, base-64 encoded Ed25519 signatures" } : null,
738
+ size: shortU16()
739
+ })
740
+ ],
741
+ ["compiledMessage", getCompiledMessageEncoder()]
742
+ ]).serialize(compiledTransaction);
743
+ }
744
+ function getTransactionEncoder() {
745
+ return {
746
+ ...BASE_CONFIG3,
747
+ deserialize: getUnimplementedDecoder("CompiledMessage"),
748
+ serialize: serialize2
749
+ };
750
+ }
751
+ function assertIsTransactionSignature(putativeTransactionSignature) {
752
+ try {
753
+ if (
754
+ // Lowest value (64 bytes of zeroes)
755
+ putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
756
+ putativeTransactionSignature.length > 88
757
+ ) {
758
+ throw new Error("Expected input string to decode to a byte array of length 64.");
759
+ }
760
+ const bytes3 = base58.serialize(putativeTransactionSignature);
761
+ const numBytes = bytes3.byteLength;
762
+ if (numBytes !== 64) {
763
+ throw new Error(`Expected input string to decode to a byte array of length 64. Actual length: ${numBytes}`);
764
+ }
765
+ } catch (e) {
766
+ throw new Error(`\`${putativeTransactionSignature}\` is not a transaction signature`, {
767
+ cause: e
768
+ });
769
+ }
770
+ }
771
+ function isTransactionSignature(putativeTransactionSignature) {
772
+ if (
773
+ // Lowest value (64 bytes of zeroes)
774
+ putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
775
+ putativeTransactionSignature.length > 88
776
+ ) {
777
+ return false;
778
+ }
779
+ const bytes3 = base58.serialize(putativeTransactionSignature);
780
+ const numBytes = bytes3.byteLength;
781
+ if (numBytes !== 64) {
782
+ return false;
783
+ }
784
+ return true;
785
+ }
606
786
  async function getCompiledMessageSignature(message, secretKey) {
607
787
  const wireMessageBytes = getCompiledMessageEncoder().serialize(message);
608
788
  const signature = await signBytes(secretKey, wireMessageBytes);
609
789
  return signature;
610
790
  }
611
- async function signTransaction(keyPair, transaction) {
791
+ function getSignatureFromTransaction(transaction) {
792
+ const signature = transaction.signatures[transaction.feePayer];
793
+ if (!signature) {
794
+ throw new Error(
795
+ "Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
796
+ );
797
+ }
798
+ return signature;
799
+ }
800
+ async function signTransaction(keyPairs, transaction) {
612
801
  const compiledMessage = compileMessage(transaction);
613
- const [signerPublicKey, signature] = await Promise.all([
614
- getBase58EncodedAddressFromPublicKey(keyPair.publicKey),
615
- getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
616
- ]);
617
- const nextSignatures = {
618
- ..."signatures" in transaction ? transaction.signatures : null,
619
- ...{ [signerPublicKey]: signature }
620
- };
802
+ const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
803
+ const publicKeySignaturePairs = await Promise.all(
804
+ keyPairs.map(
805
+ (keyPair) => Promise.all([
806
+ getAddressFromPublicKey(keyPair.publicKey),
807
+ getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
808
+ ])
809
+ )
810
+ );
811
+ for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
812
+ nextSignatures[signerPublicKey] = signature;
813
+ }
621
814
  const out = {
622
815
  ...transaction,
623
816
  signatures: nextSignatures
@@ -625,7 +818,19 @@ async function signTransaction(keyPair, transaction) {
625
818
  Object.freeze(out);
626
819
  return out;
627
820
  }
821
+ function transactionSignature(putativeTransactionSignature) {
822
+ assertIsTransactionSignature(putativeTransactionSignature);
823
+ return putativeTransactionSignature;
824
+ }
825
+
826
+ // src/wire-transaction.ts
827
+ function getBase64EncodedWireTransaction(transaction) {
828
+ const wireTransactionBytes = getTransactionEncoder().serialize(transaction);
829
+ {
830
+ return btoa(String.fromCharCode(...wireTransactionBytes));
831
+ }
832
+ }
628
833
 
629
- export { appendTransactionInstruction, createTransaction, prependTransactionInstruction, setTransactionFeePayer, signTransaction };
834
+ export { appendTransactionInstruction, assertIsBlockhash, assertIsDurableNonceTransaction, assertIsTransactionSignature, createTransaction, getBase64EncodedWireTransaction, getSignatureFromTransaction, getTransactionEncoder, isTransactionSignature, prependTransactionInstruction, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, setTransactionLifetimeUsingDurableNonce, signTransaction, transactionSignature };
630
835
  //# sourceMappingURL=out.js.map
631
836
  //# sourceMappingURL=index.native.js.map