@solana/transactions 2.0.0-experimental.c9bd7fa → 2.0.0-experimental.ca243cb

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 (36) hide show
  1. package/dist/index.browser.cjs +176 -134
  2. package/dist/index.browser.cjs.map +1 -1
  3. package/dist/index.browser.js +177 -138
  4. package/dist/index.browser.js.map +1 -1
  5. package/dist/index.native.js +177 -138
  6. package/dist/index.native.js.map +1 -1
  7. package/dist/index.node.cjs +176 -134
  8. package/dist/index.node.cjs.map +1 -1
  9. package/dist/index.node.js +177 -138
  10. package/dist/index.node.js.map +1 -1
  11. package/dist/types/blockhash.d.ts +1 -4
  12. package/dist/types/blockhash.d.ts.map +1 -1
  13. package/dist/types/compilable-transaction.d.ts +4 -4
  14. package/dist/types/compile-address-table-lookups.d.ts +1 -1
  15. package/dist/types/compile-header.d.ts +1 -1
  16. package/dist/types/compile-instructions.d.ts +1 -1
  17. package/dist/types/compile-lifetime-token.d.ts +1 -1
  18. package/dist/types/compile-static-accounts.d.ts +1 -1
  19. package/dist/types/decompile-transaction.d.ts +9 -1
  20. package/dist/types/decompile-transaction.d.ts.map +1 -1
  21. package/dist/types/fee-payer.d.ts +2 -2
  22. package/dist/types/index.d.ts +1 -0
  23. package/dist/types/index.d.ts.map +1 -1
  24. package/dist/types/message.d.ts +6 -6
  25. package/dist/types/serializers/address-table-lookup.d.ts +1 -1
  26. package/dist/types/serializers/header.d.ts +1 -1
  27. package/dist/types/serializers/instruction.d.ts +1 -1
  28. package/dist/types/serializers/transaction-version.d.ts +1 -1
  29. package/dist/types/serializers/transaction.d.ts +5 -2
  30. package/dist/types/serializers/transaction.d.ts.map +1 -1
  31. package/dist/types/signatures.d.ts.map +1 -1
  32. package/dist/types/unsigned-transaction.d.ts +1 -1
  33. package/package.json +12 -11
  34. package/dist/index.development.js +0 -1628
  35. package/dist/index.development.js.map +0 -1
  36. package/dist/index.production.min.js +0 -32
@@ -1,28 +1,12 @@
1
- import { getBase58Encoder, getBase58Decoder, getBase64Decoder, getStringEncoder, getStringDecoder } from '@solana/codecs-strings';
2
- import { getAddressFromPublicKey, getAddressComparator, getAddressEncoder, getAddressDecoder, assertIsAddress } from '@solana/addresses';
3
- import { createEncoder, mapDecoder, combineCodec, mapEncoder, createDecoder } from '@solana/codecs-core';
4
- import { getStructDecoder, getStructEncoder, getArrayEncoder, getArrayDecoder, getBytesEncoder, getBytesDecoder } from '@solana/codecs-data-structures';
5
- import { getShortU16Encoder, getShortU16Decoder, getU8Encoder, getU8Decoder } from '@solana/codecs-numbers';
1
+ import { getBase58Decoder, getBase64Decoder, getStringEncoder, getBase58Encoder, getStringDecoder } from '@solana/codecs-strings';
2
+ import { getAddressFromPublicKey, assertIsAddress, getAddressComparator, getAddressEncoder, getAddressDecoder } from '@solana/addresses';
6
3
  import { pipe } from '@solana/functional';
4
+ import { createEncoder, mapDecoder, combineCodec, mapEncoder, createDecoder } from '@solana/codecs-core';
5
+ import { getStructDecoder, getArrayDecoder, getBytesDecoder, getStructEncoder, getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';
6
+ import { getShortU16Decoder, getShortU16Encoder, getU8Encoder, getU8Decoder } from '@solana/codecs-numbers';
7
7
  import { signBytes } from '@solana/keys';
8
8
 
9
- // src/blockhash.ts
10
-
11
- // src/unsigned-transaction.ts
12
- function getUnsignedTransaction(transaction) {
13
- if ("signatures" in transaction) {
14
- const {
15
- signatures: _,
16
- // eslint-disable-line @typescript-eslint/no-unused-vars
17
- ...unsignedTransaction
18
- } = transaction;
19
- return unsignedTransaction;
20
- } else {
21
- return transaction;
22
- }
23
- }
24
-
25
- // src/blockhash.ts
9
+ // ../rpc-types/dist/index.browser.js
26
10
  var base58Encoder;
27
11
  function assertIsBlockhash(putativeBlockhash) {
28
12
  if (!base58Encoder)
@@ -46,6 +30,22 @@ function assertIsBlockhash(putativeBlockhash) {
46
30
  });
47
31
  }
48
32
  }
33
+
34
+ // src/unsigned-transaction.ts
35
+ function getUnsignedTransaction(transaction) {
36
+ if ("signatures" in transaction) {
37
+ const {
38
+ signatures: _,
39
+ // eslint-disable-line @typescript-eslint/no-unused-vars
40
+ ...unsignedTransaction
41
+ } = transaction;
42
+ return unsignedTransaction;
43
+ } else {
44
+ return transaction;
45
+ }
46
+ }
47
+
48
+ // src/blockhash.ts
49
49
  function isTransactionWithBlockhashLifetime(transaction) {
50
50
  const lifetimeConstraintShapeMatches = "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.blockhash === "string" && typeof transaction.lifetimeConstraint.lastValidBlockHeight === "bigint";
51
51
  if (!lifetimeConstraintShapeMatches)
@@ -215,6 +215,151 @@ function prependTransactionInstruction(instruction, transaction) {
215
215
  Object.freeze(out);
216
216
  return out;
217
217
  }
218
+
219
+ // src/decompile-transaction.ts
220
+ function getAccountMetas(message) {
221
+ const { header } = message;
222
+ const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
223
+ const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
224
+ const accountMetas = [];
225
+ let accountIndex = 0;
226
+ for (let i = 0; i < numWritableSignerAccounts; i++) {
227
+ accountMetas.push({
228
+ address: message.staticAccounts[accountIndex],
229
+ role: AccountRole.WRITABLE_SIGNER
230
+ });
231
+ accountIndex++;
232
+ }
233
+ for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
234
+ accountMetas.push({
235
+ address: message.staticAccounts[accountIndex],
236
+ role: AccountRole.READONLY_SIGNER
237
+ });
238
+ accountIndex++;
239
+ }
240
+ for (let i = 0; i < numWritableNonSignerAccounts; i++) {
241
+ accountMetas.push({
242
+ address: message.staticAccounts[accountIndex],
243
+ role: AccountRole.WRITABLE
244
+ });
245
+ accountIndex++;
246
+ }
247
+ for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
248
+ accountMetas.push({
249
+ address: message.staticAccounts[accountIndex],
250
+ role: AccountRole.READONLY
251
+ });
252
+ accountIndex++;
253
+ }
254
+ return accountMetas;
255
+ }
256
+ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress) {
257
+ const compiledAddressTableLookupAddresses = compiledAddressTableLookups.map((l) => l.lookupTableAddress);
258
+ const missing = compiledAddressTableLookupAddresses.filter((a) => addressesByLookupTableAddress[a] === void 0);
259
+ if (missing.length > 0) {
260
+ const missingAddresses = missing.join(", ");
261
+ throw new Error(`Addresses not provided for lookup tables: [${missingAddresses}]`);
262
+ }
263
+ const readOnlyMetas = [];
264
+ const writableMetas = [];
265
+ for (const lookup of compiledAddressTableLookups) {
266
+ const addresses = addressesByLookupTableAddress[lookup.lookupTableAddress];
267
+ const highestIndex = Math.max(...lookup.readableIndices, ...lookup.writableIndices);
268
+ if (highestIndex >= addresses.length) {
269
+ throw new Error(
270
+ `Cannot look up index ${highestIndex} in lookup table [${lookup.lookupTableAddress}]. The lookup table may have been extended since the addresses provided were retrieved.`
271
+ );
272
+ }
273
+ const readOnlyForLookup = lookup.readableIndices.map((r) => ({
274
+ address: addresses[r],
275
+ addressIndex: r,
276
+ lookupTableAddress: lookup.lookupTableAddress,
277
+ role: AccountRole.READONLY
278
+ }));
279
+ readOnlyMetas.push(...readOnlyForLookup);
280
+ const writableForLookup = lookup.writableIndices.map((w) => ({
281
+ address: addresses[w],
282
+ addressIndex: w,
283
+ lookupTableAddress: lookup.lookupTableAddress,
284
+ role: AccountRole.WRITABLE
285
+ }));
286
+ writableMetas.push(...writableForLookup);
287
+ }
288
+ return [...writableMetas, ...readOnlyMetas];
289
+ }
290
+ function convertInstruction(instruction, accountMetas) {
291
+ const programAddress = accountMetas[instruction.programAddressIndex]?.address;
292
+ if (!programAddress) {
293
+ throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
294
+ }
295
+ const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
296
+ const { data } = instruction;
297
+ return {
298
+ programAddress,
299
+ ...accounts && accounts.length ? { accounts } : {},
300
+ ...data && data.length ? { data } : {}
301
+ };
302
+ }
303
+ function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
304
+ if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
305
+ return {
306
+ blockhash: messageLifetimeToken,
307
+ lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
308
+ // U64 MAX
309
+ };
310
+ } else {
311
+ const nonceAccountAddress = firstInstruction.accounts[0].address;
312
+ assertIsAddress(nonceAccountAddress);
313
+ const nonceAuthorityAddress = firstInstruction.accounts[2].address;
314
+ assertIsAddress(nonceAuthorityAddress);
315
+ return {
316
+ nonce: messageLifetimeToken,
317
+ nonceAccountAddress,
318
+ nonceAuthorityAddress
319
+ };
320
+ }
321
+ }
322
+ function convertSignatures(compiledTransaction) {
323
+ const {
324
+ compiledMessage: { staticAccounts },
325
+ signatures
326
+ } = compiledTransaction;
327
+ return signatures.reduce((acc, sig, index) => {
328
+ const allZeros = sig.every((byte) => byte === 0);
329
+ if (allZeros)
330
+ return acc;
331
+ const address = staticAccounts[index];
332
+ return { ...acc, [address]: sig };
333
+ }, {});
334
+ }
335
+ function decompileTransaction(compiledTransaction, config) {
336
+ const { compiledMessage } = compiledTransaction;
337
+ const feePayer = compiledMessage.staticAccounts[0];
338
+ if (!feePayer)
339
+ throw new Error("No fee payer set in CompiledTransaction");
340
+ const accountMetas = getAccountMetas(compiledMessage);
341
+ const accountLookupMetas = "addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups !== void 0 && compiledMessage.addressTableLookups.length > 0 ? getAddressLookupMetas(compiledMessage.addressTableLookups, config?.addressesByLookupTableAddress ?? {}) : [];
342
+ const transactionMetas = [...accountMetas, ...accountLookupMetas];
343
+ const instructions = compiledMessage.instructions.map(
344
+ (compiledInstruction) => convertInstruction(compiledInstruction, transactionMetas)
345
+ );
346
+ const firstInstruction = instructions[0];
347
+ const lifetimeConstraint = getLifetimeConstraint(
348
+ compiledMessage.lifetimeToken,
349
+ firstInstruction,
350
+ config?.lastValidBlockHeight
351
+ );
352
+ const signatures = convertSignatures(compiledTransaction);
353
+ return pipe(
354
+ createTransaction({ version: compiledMessage.version }),
355
+ (tx) => setTransactionFeePayer(feePayer, tx),
356
+ (tx) => instructions.reduce((acc, instruction) => {
357
+ return appendTransactionInstruction(instruction, acc);
358
+ }, tx),
359
+ (tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
360
+ (tx) => Object.keys(signatures).length > 0 ? { ...tx, signatures } : tx
361
+ );
362
+ }
218
363
  function upsert(addressMap, address, update) {
219
364
  addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
220
365
  }
@@ -708,116 +853,6 @@ function getCompiledTransaction(transaction) {
708
853
  signatures
709
854
  };
710
855
  }
711
- function getAccountMetas(message) {
712
- const { header } = message;
713
- const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
714
- const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
715
- const accountMetas = [];
716
- let accountIndex = 0;
717
- for (let i = 0; i < numWritableSignerAccounts; i++) {
718
- accountMetas.push({
719
- address: message.staticAccounts[accountIndex],
720
- role: AccountRole.WRITABLE_SIGNER
721
- });
722
- accountIndex++;
723
- }
724
- for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
725
- accountMetas.push({
726
- address: message.staticAccounts[accountIndex],
727
- role: AccountRole.READONLY_SIGNER
728
- });
729
- accountIndex++;
730
- }
731
- for (let i = 0; i < numWritableNonSignerAccounts; i++) {
732
- accountMetas.push({
733
- address: message.staticAccounts[accountIndex],
734
- role: AccountRole.WRITABLE
735
- });
736
- accountIndex++;
737
- }
738
- for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
739
- accountMetas.push({
740
- address: message.staticAccounts[accountIndex],
741
- role: AccountRole.READONLY
742
- });
743
- accountIndex++;
744
- }
745
- return accountMetas;
746
- }
747
- function convertInstruction(instruction, accountMetas) {
748
- const programAddress = accountMetas[instruction.programAddressIndex]?.address;
749
- if (!programAddress) {
750
- throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
751
- }
752
- const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
753
- const { data } = instruction;
754
- return {
755
- programAddress,
756
- ...accounts && accounts.length ? { accounts } : {},
757
- ...data && data.length ? { data } : {}
758
- };
759
- }
760
- function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
761
- if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
762
- return {
763
- blockhash: messageLifetimeToken,
764
- lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
765
- // U64 MAX
766
- };
767
- } else {
768
- const nonceAccountAddress = firstInstruction.accounts[0].address;
769
- assertIsAddress(nonceAccountAddress);
770
- const nonceAuthorityAddress = firstInstruction.accounts[2].address;
771
- assertIsAddress(nonceAuthorityAddress);
772
- return {
773
- nonce: messageLifetimeToken,
774
- nonceAccountAddress,
775
- nonceAuthorityAddress
776
- };
777
- }
778
- }
779
- function convertSignatures(compiledTransaction) {
780
- const {
781
- compiledMessage: { staticAccounts },
782
- signatures
783
- } = compiledTransaction;
784
- return signatures.reduce((acc, sig, index) => {
785
- const allZeros = sig.every((byte) => byte === 0);
786
- if (allZeros)
787
- return acc;
788
- const address = staticAccounts[index];
789
- return { ...acc, [address]: sig };
790
- }, {});
791
- }
792
- function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
793
- const { compiledMessage } = compiledTransaction;
794
- if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
795
- throw new Error("Cannot convert transaction with addressTableLookups");
796
- }
797
- const feePayer = compiledMessage.staticAccounts[0];
798
- if (!feePayer)
799
- throw new Error("No fee payer set in CompiledTransaction");
800
- const accountMetas = getAccountMetas(compiledMessage);
801
- const instructions = compiledMessage.instructions.map(
802
- (compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
803
- );
804
- const firstInstruction = instructions[0];
805
- const lifetimeConstraint = getLifetimeConstraint(
806
- compiledMessage.lifetimeToken,
807
- firstInstruction,
808
- lastValidBlockHeight
809
- );
810
- const signatures = convertSignatures(compiledTransaction);
811
- return pipe(
812
- createTransaction({ version: compiledMessage.version }),
813
- (tx) => setTransactionFeePayer(feePayer, tx),
814
- (tx) => instructions.reduce((acc, instruction) => {
815
- return appendTransactionInstruction(instruction, acc);
816
- }, tx),
817
- (tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
818
- (tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
819
- );
820
- }
821
856
 
822
857
  // src/serializers/transaction.ts
823
858
  function getCompiledTransactionEncoder() {
@@ -840,14 +875,14 @@ function getCompiledTransactionDecoder() {
840
875
  function getTransactionEncoder() {
841
876
  return mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
842
877
  }
843
- function getTransactionDecoder(lastValidBlockHeight) {
878
+ function getTransactionDecoder(config) {
844
879
  return mapDecoder(
845
880
  getCompiledTransactionDecoder(),
846
- (compiledTransaction) => decompileTransaction(compiledTransaction, lastValidBlockHeight)
881
+ (compiledTransaction) => decompileTransaction(compiledTransaction, config)
847
882
  );
848
883
  }
849
- function getTransactionCodec(lastValidBlockHeight) {
850
- return combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
884
+ function getTransactionCodec(config) {
885
+ return combineCodec(getTransactionEncoder(), getTransactionDecoder(config));
851
886
  }
852
887
  var base58Decoder;
853
888
  function getSignatureFromTransaction(transaction) {
@@ -890,17 +925,21 @@ async function signTransaction(keyPairs, transaction) {
890
925
  function assertTransactionIsFullySigned(transaction) {
891
926
  const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
892
927
  const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
928
+ const missingSigs = [];
893
929
  requiredSigners.forEach((address) => {
894
930
  if (!transaction.signatures[address]) {
895
- throw new Error(`Transaction is missing signature for address \`${address}\``);
931
+ missingSigs.push(address);
896
932
  }
897
933
  });
934
+ if (missingSigs.length > 0) {
935
+ throw new Error("Transaction is missing signatures for addresses: " + missingSigs.join(", "));
936
+ }
898
937
  }
899
938
  function getBase64EncodedWireTransaction(transaction) {
900
939
  const wireTransactionBytes = getTransactionEncoder().encode(transaction);
901
940
  return getBase64Decoder().decode(wireTransactionBytes);
902
941
  }
903
942
 
904
- export { appendTransactionInstruction, assertIsBlockhash, assertIsDurableNonceTransaction, assertIsTransactionWithBlockhashLifetime, assertTransactionIsFullySigned, compileMessage, createTransaction, getBase64EncodedWireTransaction, getCompiledMessageCodec, getCompiledMessageDecoder, getCompiledMessageEncoder, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, isAdvanceNonceAccountInstruction, partiallySignTransaction, prependTransactionInstruction, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, setTransactionLifetimeUsingDurableNonce, signTransaction };
943
+ export { appendTransactionInstruction, assertIsDurableNonceTransaction, assertIsTransactionWithBlockhashLifetime, assertTransactionIsFullySigned, compileMessage, createTransaction, decompileTransaction, getBase64EncodedWireTransaction, getCompiledMessageCodec, getCompiledMessageDecoder, getCompiledMessageEncoder, getCompiledTransactionDecoder, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, isAdvanceNonceAccountInstruction, partiallySignTransaction, prependTransactionInstruction, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, setTransactionLifetimeUsingDurableNonce, signTransaction };
905
944
  //# sourceMappingURL=out.js.map
906
945
  //# sourceMappingURL=index.browser.js.map