@solana/transactions 2.0.0-experimental.2bae733 → 2.0.0-experimental.2f6fdd4

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 (52) hide show
  1. package/dist/index.browser.cjs +204 -68
  2. package/dist/index.browser.cjs.map +1 -1
  3. package/dist/index.browser.js +196 -67
  4. package/dist/index.browser.js.map +1 -1
  5. package/dist/index.development.js +264 -125
  6. package/dist/index.development.js.map +1 -1
  7. package/dist/index.native.js +196 -65
  8. package/dist/index.native.js.map +1 -1
  9. package/dist/index.node.cjs +206 -68
  10. package/dist/index.node.cjs.map +1 -1
  11. package/dist/index.node.js +196 -65
  12. package/dist/index.node.js.map +1 -1
  13. package/dist/index.production.min.js +11 -6
  14. package/dist/types/accounts.d.ts +1 -1
  15. package/dist/types/accounts.d.ts.map +1 -0
  16. package/dist/types/blockhash.d.ts +9 -1
  17. package/dist/types/blockhash.d.ts.map +1 -0
  18. package/dist/types/compile-address-table-lookups.d.ts +1 -1
  19. package/dist/types/compile-address-table-lookups.d.ts.map +1 -0
  20. package/dist/types/compile-header.d.ts.map +1 -0
  21. package/dist/types/compile-instructions.d.ts +1 -1
  22. package/dist/types/compile-instructions.d.ts.map +1 -0
  23. package/dist/types/compile-lifetime-token.d.ts.map +1 -0
  24. package/dist/types/compile-static-accounts.d.ts +1 -1
  25. package/dist/types/compile-static-accounts.d.ts.map +1 -0
  26. package/dist/types/compile-transaction.d.ts +11 -0
  27. package/dist/types/compile-transaction.d.ts.map +1 -0
  28. package/dist/types/create-transaction.d.ts.map +1 -0
  29. package/dist/types/durable-nonce.d.ts +18 -6
  30. package/dist/types/durable-nonce.d.ts.map +1 -0
  31. package/dist/types/fee-payer.d.ts +1 -1
  32. package/dist/types/fee-payer.d.ts.map +1 -0
  33. package/dist/types/index.d.ts +1 -0
  34. package/dist/types/index.d.ts.map +1 -0
  35. package/dist/types/instructions.d.ts.map +1 -0
  36. package/dist/types/message.d.ts.map +1 -0
  37. package/dist/types/serializers/address-table-lookup.d.ts.map +1 -0
  38. package/dist/types/serializers/header.d.ts.map +1 -0
  39. package/dist/types/serializers/instruction.d.ts.map +1 -0
  40. package/dist/types/serializers/message.d.ts.map +1 -0
  41. package/dist/types/serializers/transaction-version.d.ts.map +1 -0
  42. package/dist/types/serializers/transaction.d.ts +6 -0
  43. package/dist/types/serializers/transaction.d.ts.map +1 -0
  44. package/dist/types/serializers/unimplemented.d.ts.map +1 -0
  45. package/dist/types/signatures.d.ts +3 -4
  46. package/dist/types/signatures.d.ts.map +1 -0
  47. package/dist/types/types.d.ts.map +1 -0
  48. package/dist/types/unsigned-transaction.d.ts +4 -0
  49. package/dist/types/unsigned-transaction.d.ts.map +1 -0
  50. package/dist/types/wire-transaction.d.ts +6 -0
  51. package/dist/types/wire-transaction.d.ts.map +1 -0
  52. package/package.json +12 -16
@@ -1,79 +1,67 @@
1
1
  'use strict';
2
2
 
3
- var keys = require('@solana/keys');
4
3
  var umiSerializers = require('@metaplex-foundation/umi-serializers');
4
+ var addresses = require('@solana/addresses');
5
+ var keys = require('@solana/keys');
5
6
 
6
7
  // ../build-scripts/env-shim.ts
7
8
  var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
8
9
 
9
- // src/create-transaction.ts
10
- function createTransaction({
11
- version
12
- }) {
13
- const out = {
14
- instructions: [],
15
- version
16
- };
17
- Object.freeze(out);
18
- return out;
19
- }
20
-
21
- // src/fee-payer.ts
22
- function setTransactionFeePayer(feePayer, transaction) {
23
- if ("feePayer" in transaction && feePayer === transaction.feePayer) {
24
- return transaction;
25
- }
26
- let out;
10
+ // src/unsigned-transaction.ts
11
+ function getUnsignedTransaction(transaction) {
27
12
  if ("signatures" in transaction) {
28
13
  const {
29
14
  signatures: _,
30
15
  // eslint-disable-line @typescript-eslint/no-unused-vars
31
16
  ...unsignedTransaction
32
17
  } = transaction;
33
- out = {
34
- ...unsignedTransaction,
35
- feePayer
36
- };
18
+ return unsignedTransaction;
37
19
  } else {
38
- out = {
39
- ...transaction,
40
- feePayer
41
- };
20
+ return transaction;
42
21
  }
43
- Object.freeze(out);
44
- return out;
45
22
  }
46
23
 
47
- // src/instructions.ts
48
- function replaceInstructions(transaction, nextInstructions) {
49
- let out;
50
- if ("signatures" in transaction) {
51
- const {
52
- signatures: _,
53
- // eslint-disable-line @typescript-eslint/no-unused-vars
54
- ...unsignedTransaction
55
- } = transaction;
56
- out = {
57
- ...unsignedTransaction,
58
- instructions: nextInstructions
59
- };
60
- } else {
61
- out = {
62
- ...transaction,
63
- instructions: nextInstructions
64
- };
24
+ // src/blockhash.ts
25
+ function assertIsBlockhash(putativeBlockhash) {
26
+ try {
27
+ if (
28
+ // Lowest value (32 bytes of zeroes)
29
+ putativeBlockhash.length < 32 || // Highest value (32 bytes of 255)
30
+ putativeBlockhash.length > 44
31
+ ) {
32
+ throw new Error("Expected input string to decode to a byte array of length 32.");
33
+ }
34
+ const bytes3 = umiSerializers.base58.serialize(putativeBlockhash);
35
+ const numBytes = bytes3.byteLength;
36
+ if (numBytes !== 32) {
37
+ throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
38
+ }
39
+ } catch (e) {
40
+ throw new Error(`\`${putativeBlockhash}\` is not a blockhash`, {
41
+ cause: e
42
+ });
65
43
  }
66
- return out;
67
44
  }
68
- function appendTransactionInstruction(instruction, transaction) {
69
- const nextInstructions = [...transaction.instructions, instruction];
70
- const out = replaceInstructions(transaction, nextInstructions);
45
+ function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
46
+ if ("lifetimeConstraint" in transaction && transaction.lifetimeConstraint.blockhash === blockhashLifetimeConstraint.blockhash && transaction.lifetimeConstraint.lastValidBlockHeight === blockhashLifetimeConstraint.lastValidBlockHeight) {
47
+ return transaction;
48
+ }
49
+ const out = {
50
+ ...getUnsignedTransaction(transaction),
51
+ lifetimeConstraint: blockhashLifetimeConstraint
52
+ };
71
53
  Object.freeze(out);
72
54
  return out;
73
55
  }
74
- function prependTransactionInstruction(instruction, transaction) {
75
- const nextInstructions = [instruction, ...transaction.instructions];
76
- const out = replaceInstructions(transaction, nextInstructions);
56
+
57
+ // src/create-transaction.ts
58
+ function createTransaction({
59
+ version
60
+ }) {
61
+ const out = {
62
+ instructions: [],
63
+ version
64
+ };
77
65
  Object.freeze(out);
78
66
  return out;
79
67
  }
@@ -100,6 +88,96 @@ function isWritableRole(role) {
100
88
  function mergeRoles(roleA, roleB) {
101
89
  return roleA | roleB;
102
90
  }
91
+
92
+ // src/durable-nonce.ts
93
+ var RECENT_BLOCKHASHES_SYSVAR_ADDRESS = "SysvarRecentB1ockHashes11111111111111111111";
94
+ var SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
95
+ function assertIsDurableNonceTransaction(transaction) {
96
+ if (!isDurableNonceTransaction(transaction)) {
97
+ throw new Error("Transaction is not a durable nonce transaction");
98
+ }
99
+ }
100
+ function createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress) {
101
+ return {
102
+ accounts: [
103
+ { address: nonceAccountAddress, role: AccountRole.WRITABLE },
104
+ {
105
+ address: RECENT_BLOCKHASHES_SYSVAR_ADDRESS,
106
+ role: AccountRole.READONLY
107
+ },
108
+ { address: nonceAuthorityAddress, role: AccountRole.READONLY_SIGNER }
109
+ ],
110
+ data: new Uint8Array([4, 0, 0, 0]),
111
+ programAddress: SYSTEM_PROGRAM_ADDRESS
112
+ };
113
+ }
114
+ function isAdvanceNonceAccountInstruction(instruction) {
115
+ return instruction.programAddress === SYSTEM_PROGRAM_ADDRESS && // Test for `AdvanceNonceAccount` instruction data
116
+ instruction.data != null && isAdvanceNonceAccountInstructionData(instruction.data) && // Test for exactly 3 accounts
117
+ instruction.accounts?.length === 3 && // First account is nonce account address
118
+ instruction.accounts[0].address != null && instruction.accounts[0].role === AccountRole.WRITABLE && // Second account is recent blockhashes sysvar
119
+ instruction.accounts[1].address === RECENT_BLOCKHASHES_SYSVAR_ADDRESS && instruction.accounts[1].role === AccountRole.READONLY && // Third account is nonce authority account
120
+ instruction.accounts[2].address != null && instruction.accounts[2].role === AccountRole.READONLY_SIGNER;
121
+ }
122
+ function isAdvanceNonceAccountInstructionData(data) {
123
+ return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;
124
+ }
125
+ function isDurableNonceTransaction(transaction) {
126
+ return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
127
+ }
128
+ function setTransactionLifetimeUsingDurableNonce({
129
+ nonce,
130
+ nonceAccountAddress,
131
+ nonceAuthorityAddress
132
+ }, transaction) {
133
+ const isAlreadyDurableNonceTransaction = isDurableNonceTransaction(transaction);
134
+ if (isAlreadyDurableNonceTransaction && transaction.lifetimeConstraint.nonce === nonce && transaction.instructions[0].accounts[0].address === nonceAccountAddress && transaction.instructions[0].accounts[2].address === nonceAuthorityAddress) {
135
+ return transaction;
136
+ }
137
+ const out = {
138
+ ...getUnsignedTransaction(transaction),
139
+ instructions: [
140
+ createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
141
+ ...isAlreadyDurableNonceTransaction ? transaction.instructions.slice(1) : transaction.instructions
142
+ ],
143
+ lifetimeConstraint: {
144
+ nonce
145
+ }
146
+ };
147
+ Object.freeze(out);
148
+ return out;
149
+ }
150
+
151
+ // src/fee-payer.ts
152
+ function setTransactionFeePayer(feePayer, transaction) {
153
+ if ("feePayer" in transaction && feePayer === transaction.feePayer) {
154
+ return transaction;
155
+ }
156
+ const out = {
157
+ ...getUnsignedTransaction(transaction),
158
+ feePayer
159
+ };
160
+ Object.freeze(out);
161
+ return out;
162
+ }
163
+
164
+ // src/instructions.ts
165
+ function appendTransactionInstruction(instruction, transaction) {
166
+ const out = {
167
+ ...getUnsignedTransaction(transaction),
168
+ instructions: [...transaction.instructions, instruction]
169
+ };
170
+ Object.freeze(out);
171
+ return out;
172
+ }
173
+ function prependTransactionInstruction(instruction, transaction) {
174
+ const out = {
175
+ ...getUnsignedTransaction(transaction),
176
+ instructions: [instruction, ...transaction.instructions]
177
+ };
178
+ Object.freeze(out);
179
+ return out;
180
+ }
103
181
  function upsert(addressMap, address, update) {
104
182
  addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
105
183
  }
@@ -152,7 +230,7 @@ function getAddressMapFromInstructions(feePayer, instructions) {
152
230
  const shouldReplaceEntry = (
153
231
  // Consider using the new LOOKUP_TABLE if its address is different...
154
232
  entry.lookupTableAddress !== accountMeta.lookupTableAddress && // ...and sorts before the existing one.
155
- (addressComparator || (addressComparator = keys.getBase58EncodedAddressComparator()))(
233
+ (addressComparator || (addressComparator = addresses.getBase58EncodedAddressComparator()))(
156
234
  accountMeta.lookupTableAddress,
157
235
  entry.lookupTableAddress
158
236
  ) < 0
@@ -258,7 +336,7 @@ function getOrderedAccountsFromAddressMap(addressMap) {
258
336
  if (leftIsWritable !== isWritableRole(rightEntry.role)) {
259
337
  return leftIsWritable ? -1 : 1;
260
338
  }
261
- addressComparator || (addressComparator = keys.getBase58EncodedAddressComparator());
339
+ addressComparator || (addressComparator = addresses.getBase58EncodedAddressComparator());
262
340
  if (leftEntry[TYPE] === 1 /* LOOKUP_TABLE */ && rightEntry[TYPE] === 1 /* LOOKUP_TABLE */ && leftEntry.lookupTableAddress !== rightEntry.lookupTableAddress) {
263
341
  return addressComparator(leftEntry.lookupTableAddress, rightEntry.lookupTableAddress);
264
342
  } else {
@@ -287,7 +365,7 @@ function getCompiledAddressTableLookups(orderedAccounts) {
287
365
  entry.readableIndices.push(account.addressIndex);
288
366
  }
289
367
  }
290
- return Object.keys(index).sort(keys.getBase58EncodedAddressComparator()).map((lookupTableAddress) => ({
368
+ return Object.keys(index).sort(addresses.getBase58EncodedAddressComparator()).map((lookupTableAddress) => ({
291
369
  lookupTableAddress,
292
370
  ...index[lookupTableAddress]
293
371
  }));
@@ -371,7 +449,7 @@ function getAddressTableLookupCodec() {
371
449
  [
372
450
  [
373
451
  "lookupTableAddress",
374
- keys.getBase58EncodedAddressCodec(
452
+ addresses.getBase58EncodedAddressCodec(
375
453
  __DEV__ ? {
376
454
  description: "The address of the address lookup table account from which instruction addresses should be looked up"
377
455
  } : void 0
@@ -446,7 +524,7 @@ function getInstructionCodec() {
446
524
  )
447
525
  ],
448
526
  [
449
- "addressIndices",
527
+ "accountIndices",
450
528
  umiSerializers.array(
451
529
  umiSerializers.u8({
452
530
  description: __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : ""
@@ -466,23 +544,23 @@ function getInstructionCodec() {
466
544
  ]
467
545
  ]),
468
546
  (value) => {
469
- if (value.addressIndices !== void 0 && value.data !== void 0) {
547
+ if (value.accountIndices !== void 0 && value.data !== void 0) {
470
548
  return value;
471
549
  }
472
550
  return {
473
551
  ...value,
474
- addressIndices: value.addressIndices ?? [],
552
+ accountIndices: value.accountIndices ?? [],
475
553
  data: value.data ?? new Uint8Array(0)
476
554
  };
477
555
  },
478
556
  (value) => {
479
- if (value.addressIndices.length && value.data.byteLength) {
557
+ if (value.accountIndices.length && value.data.byteLength) {
480
558
  return value;
481
559
  }
482
- const { addressIndices, data, ...rest } = value;
560
+ const { accountIndices, data, ...rest } = value;
483
561
  return {
484
562
  ...rest,
485
- ...addressIndices.length ? { addressIndices } : null,
563
+ ...accountIndices.length ? { accountIndices } : null,
486
564
  ...data.byteLength ? { data } : null
487
565
  };
488
566
  }
@@ -509,8 +587,8 @@ var BASE_CONFIG = {
509
587
  fixedSize: null,
510
588
  maxSize: 1
511
589
  };
512
- function deserialize(bytes2, offset = 0) {
513
- const firstByte = bytes2[offset];
590
+ function deserialize(bytes3, offset = 0) {
591
+ const firstByte = bytes3[offset];
514
592
  if ((firstByte & VERSION_FLAG_MASK) === 0) {
515
593
  return ["legacy", offset];
516
594
  } else {
@@ -568,7 +646,7 @@ function getPreludeStructSerializerTuple() {
568
646
  ["header", getMessageHeaderCodec()],
569
647
  [
570
648
  "staticAccounts",
571
- umiSerializers.array(keys.getBase58EncodedAddressCodec(), {
649
+ umiSerializers.array(addresses.getBase58EncodedAddressCodec(), {
572
650
  description: __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "",
573
651
  size: umiSerializers.shortU16()
574
652
  })
@@ -613,7 +691,7 @@ async function getCompiledMessageSignature(message, secretKey) {
613
691
  async function signTransaction(keyPair, transaction) {
614
692
  const compiledMessage = compileMessage(transaction);
615
693
  const [signerPublicKey, signature] = await Promise.all([
616
- keys.getBase58EncodedAddressFromPublicKey(keyPair.publicKey),
694
+ addresses.getAddressFromPublicKey(keyPair.publicKey),
617
695
  getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
618
696
  ]);
619
697
  const nextSignatures = {
@@ -628,8 +706,66 @@ async function signTransaction(keyPair, transaction) {
628
706
  return out;
629
707
  }
630
708
 
709
+ // src/compile-transaction.ts
710
+ function getCompiledTransaction(transaction) {
711
+ const compiledMessage = compileMessage(transaction);
712
+ let signatures;
713
+ if ("signatures" in transaction) {
714
+ signatures = [];
715
+ for (let ii = 0; ii < compiledMessage.header.numSignerAccounts; ii++) {
716
+ signatures[ii] = transaction.signatures[compiledMessage.staticAccounts[ii]] ?? new Uint8Array(Array(64).fill(0));
717
+ }
718
+ } else {
719
+ signatures = Array(compiledMessage.header.numSignerAccounts).fill(new Uint8Array(Array(64).fill(0)));
720
+ }
721
+ return {
722
+ compiledMessage,
723
+ signatures
724
+ };
725
+ }
726
+
727
+ // 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 serialize3(transaction) {
734
+ const compiledTransaction = getCompiledTransaction(transaction);
735
+ return umiSerializers.struct([
736
+ [
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
+ })
742
+ ],
743
+ ["compiledMessage", getCompiledMessageEncoder()]
744
+ ]).serialize(compiledTransaction);
745
+ }
746
+ function getTransactionEncoder() {
747
+ return {
748
+ ...BASE_CONFIG3,
749
+ deserialize: getUnimplementedDecoder("CompiledMessage"),
750
+ serialize: serialize3
751
+ };
752
+ }
753
+
754
+ // src/wire-transaction.ts
755
+ function getBase64EncodedWireTransaction(transaction) {
756
+ const wireTransactionBytes = getTransactionEncoder().serialize(transaction);
757
+ {
758
+ return btoa(String.fromCharCode(...wireTransactionBytes));
759
+ }
760
+ }
761
+
631
762
  exports.appendTransactionInstruction = appendTransactionInstruction;
763
+ exports.assertIsBlockhash = assertIsBlockhash;
764
+ exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
632
765
  exports.createTransaction = createTransaction;
766
+ exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
633
767
  exports.prependTransactionInstruction = prependTransactionInstruction;
634
768
  exports.setTransactionFeePayer = setTransactionFeePayer;
769
+ exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
770
+ exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
635
771
  exports.signTransaction = signTransaction;