@solana/transactions 2.0.0-experimental.e1ca396 → 2.0.0-experimental.e58bb22

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 (44) hide show
  1. package/dist/index.browser.cjs +178 -137
  2. package/dist/index.browser.cjs.map +1 -1
  3. package/dist/index.browser.js +181 -141
  4. package/dist/index.browser.js.map +1 -1
  5. package/dist/index.native.js +181 -141
  6. package/dist/index.native.js.map +1 -1
  7. package/dist/index.node.cjs +178 -137
  8. package/dist/index.node.cjs.map +1 -1
  9. package/dist/index.node.js +183 -141
  10. package/dist/index.node.js.map +1 -1
  11. package/dist/types/blockhash.d.ts +4 -7
  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/compile-transaction.d.ts +3 -3
  20. package/dist/types/create-transaction.d.ts +1 -1
  21. package/dist/types/decompile-transaction.d.ts +12 -4
  22. package/dist/types/decompile-transaction.d.ts.map +1 -1
  23. package/dist/types/durable-nonce.d.ts +2 -2
  24. package/dist/types/fee-payer.d.ts +2 -2
  25. package/dist/types/index.d.ts +12 -11
  26. package/dist/types/index.d.ts.map +1 -1
  27. package/dist/types/instructions.d.ts +2 -2
  28. package/dist/types/message.d.ts +6 -6
  29. package/dist/types/serializers/address-table-lookup.d.ts +1 -1
  30. package/dist/types/serializers/header.d.ts +1 -1
  31. package/dist/types/serializers/index.d.ts +2 -2
  32. package/dist/types/serializers/instruction.d.ts +1 -1
  33. package/dist/types/serializers/message.d.ts +1 -1
  34. package/dist/types/serializers/transaction-version.d.ts +1 -1
  35. package/dist/types/serializers/transaction.d.ts +7 -4
  36. package/dist/types/serializers/transaction.d.ts.map +1 -1
  37. package/dist/types/signatures.d.ts +2 -2
  38. package/dist/types/signatures.d.ts.map +1 -1
  39. package/dist/types/unsigned-transaction.d.ts +1 -1
  40. package/dist/types/wire-transaction.d.ts +1 -1
  41. package/package.json +17 -15
  42. package/dist/index.development.js +0 -1628
  43. package/dist/index.development.js.map +0 -1
  44. package/dist/index.production.min.js +0 -32
@@ -1,28 +1,13 @@
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
+ import { SolanaError, SOLANA_ERROR__TRANSACTION_SIGNATURE_NOT_COMPUTABLE, SOLANA_ERROR__TRANSACTION_MISSING_SIGNATURES } from '@solana/errors';
7
8
  import { signBytes } from '@solana/keys';
8
9
 
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
10
+ // ../rpc-types/dist/index.browser.js
26
11
  var base58Encoder;
27
12
  function assertIsBlockhash(putativeBlockhash) {
28
13
  if (!base58Encoder)
@@ -46,6 +31,22 @@ function assertIsBlockhash(putativeBlockhash) {
46
31
  });
47
32
  }
48
33
  }
34
+
35
+ // src/unsigned-transaction.ts
36
+ function getUnsignedTransaction(transaction) {
37
+ if ("signatures" in transaction) {
38
+ const {
39
+ signatures: _,
40
+ // eslint-disable-line @typescript-eslint/no-unused-vars
41
+ ...unsignedTransaction
42
+ } = transaction;
43
+ return unsignedTransaction;
44
+ } else {
45
+ return transaction;
46
+ }
47
+ }
48
+
49
+ // src/blockhash.ts
49
50
  function isTransactionWithBlockhashLifetime(transaction) {
50
51
  const lifetimeConstraintShapeMatches = "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.blockhash === "string" && typeof transaction.lifetimeConstraint.lastValidBlockHeight === "bigint";
51
52
  if (!lifetimeConstraintShapeMatches)
@@ -215,6 +216,151 @@ function prependTransactionInstruction(instruction, transaction) {
215
216
  Object.freeze(out);
216
217
  return out;
217
218
  }
219
+
220
+ // src/decompile-transaction.ts
221
+ function getAccountMetas(message) {
222
+ const { header } = message;
223
+ const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
224
+ const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
225
+ const accountMetas = [];
226
+ let accountIndex = 0;
227
+ for (let i = 0; i < numWritableSignerAccounts; i++) {
228
+ accountMetas.push({
229
+ address: message.staticAccounts[accountIndex],
230
+ role: AccountRole.WRITABLE_SIGNER
231
+ });
232
+ accountIndex++;
233
+ }
234
+ for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
235
+ accountMetas.push({
236
+ address: message.staticAccounts[accountIndex],
237
+ role: AccountRole.READONLY_SIGNER
238
+ });
239
+ accountIndex++;
240
+ }
241
+ for (let i = 0; i < numWritableNonSignerAccounts; i++) {
242
+ accountMetas.push({
243
+ address: message.staticAccounts[accountIndex],
244
+ role: AccountRole.WRITABLE
245
+ });
246
+ accountIndex++;
247
+ }
248
+ for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
249
+ accountMetas.push({
250
+ address: message.staticAccounts[accountIndex],
251
+ role: AccountRole.READONLY
252
+ });
253
+ accountIndex++;
254
+ }
255
+ return accountMetas;
256
+ }
257
+ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress) {
258
+ const compiledAddressTableLookupAddresses = compiledAddressTableLookups.map((l) => l.lookupTableAddress);
259
+ const missing = compiledAddressTableLookupAddresses.filter((a) => addressesByLookupTableAddress[a] === void 0);
260
+ if (missing.length > 0) {
261
+ const missingAddresses = missing.join(", ");
262
+ throw new Error(`Addresses not provided for lookup tables: [${missingAddresses}]`);
263
+ }
264
+ const readOnlyMetas = [];
265
+ const writableMetas = [];
266
+ for (const lookup of compiledAddressTableLookups) {
267
+ const addresses = addressesByLookupTableAddress[lookup.lookupTableAddress];
268
+ const highestIndex = Math.max(...lookup.readableIndices, ...lookup.writableIndices);
269
+ if (highestIndex >= addresses.length) {
270
+ throw new Error(
271
+ `Cannot look up index ${highestIndex} in lookup table [${lookup.lookupTableAddress}]. The lookup table may have been extended since the addresses provided were retrieved.`
272
+ );
273
+ }
274
+ const readOnlyForLookup = lookup.readableIndices.map((r) => ({
275
+ address: addresses[r],
276
+ addressIndex: r,
277
+ lookupTableAddress: lookup.lookupTableAddress,
278
+ role: AccountRole.READONLY
279
+ }));
280
+ readOnlyMetas.push(...readOnlyForLookup);
281
+ const writableForLookup = lookup.writableIndices.map((w) => ({
282
+ address: addresses[w],
283
+ addressIndex: w,
284
+ lookupTableAddress: lookup.lookupTableAddress,
285
+ role: AccountRole.WRITABLE
286
+ }));
287
+ writableMetas.push(...writableForLookup);
288
+ }
289
+ return [...writableMetas, ...readOnlyMetas];
290
+ }
291
+ function convertInstruction(instruction, accountMetas) {
292
+ const programAddress = accountMetas[instruction.programAddressIndex]?.address;
293
+ if (!programAddress) {
294
+ throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
295
+ }
296
+ const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
297
+ const { data } = instruction;
298
+ return {
299
+ programAddress,
300
+ ...accounts && accounts.length ? { accounts } : {},
301
+ ...data && data.length ? { data } : {}
302
+ };
303
+ }
304
+ function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
305
+ if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
306
+ return {
307
+ blockhash: messageLifetimeToken,
308
+ lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
309
+ // U64 MAX
310
+ };
311
+ } else {
312
+ const nonceAccountAddress = firstInstruction.accounts[0].address;
313
+ assertIsAddress(nonceAccountAddress);
314
+ const nonceAuthorityAddress = firstInstruction.accounts[2].address;
315
+ assertIsAddress(nonceAuthorityAddress);
316
+ return {
317
+ nonce: messageLifetimeToken,
318
+ nonceAccountAddress,
319
+ nonceAuthorityAddress
320
+ };
321
+ }
322
+ }
323
+ function convertSignatures(compiledTransaction) {
324
+ const {
325
+ compiledMessage: { staticAccounts },
326
+ signatures
327
+ } = compiledTransaction;
328
+ return signatures.reduce((acc, sig, index) => {
329
+ const allZeros = sig.every((byte) => byte === 0);
330
+ if (allZeros)
331
+ return acc;
332
+ const address = staticAccounts[index];
333
+ return { ...acc, [address]: sig };
334
+ }, {});
335
+ }
336
+ function decompileTransaction(compiledTransaction, config) {
337
+ const { compiledMessage } = compiledTransaction;
338
+ const feePayer = compiledMessage.staticAccounts[0];
339
+ if (!feePayer)
340
+ throw new Error("No fee payer set in CompiledTransaction");
341
+ const accountMetas = getAccountMetas(compiledMessage);
342
+ const accountLookupMetas = "addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups !== void 0 && compiledMessage.addressTableLookups.length > 0 ? getAddressLookupMetas(compiledMessage.addressTableLookups, config?.addressesByLookupTableAddress ?? {}) : [];
343
+ const transactionMetas = [...accountMetas, ...accountLookupMetas];
344
+ const instructions = compiledMessage.instructions.map(
345
+ (compiledInstruction) => convertInstruction(compiledInstruction, transactionMetas)
346
+ );
347
+ const firstInstruction = instructions[0];
348
+ const lifetimeConstraint = getLifetimeConstraint(
349
+ compiledMessage.lifetimeToken,
350
+ firstInstruction,
351
+ config?.lastValidBlockHeight
352
+ );
353
+ const signatures = convertSignatures(compiledTransaction);
354
+ return pipe(
355
+ createTransaction({ version: compiledMessage.version }),
356
+ (tx) => setTransactionFeePayer(feePayer, tx),
357
+ (tx) => instructions.reduce((acc, instruction) => {
358
+ return appendTransactionInstruction(instruction, acc);
359
+ }, tx),
360
+ (tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
361
+ (tx) => Object.keys(signatures).length > 0 ? { ...tx, signatures } : tx
362
+ );
363
+ }
218
364
  function upsert(addressMap, address, update) {
219
365
  addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
220
366
  }
@@ -708,116 +854,6 @@ function getCompiledTransaction(transaction) {
708
854
  signatures
709
855
  };
710
856
  }
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
857
 
822
858
  // src/serializers/transaction.ts
823
859
  function getCompiledTransactionEncoder() {
@@ -840,14 +876,14 @@ function getCompiledTransactionDecoder() {
840
876
  function getTransactionEncoder() {
841
877
  return mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
842
878
  }
843
- function getTransactionDecoder(lastValidBlockHeight) {
879
+ function getTransactionDecoder(config) {
844
880
  return mapDecoder(
845
881
  getCompiledTransactionDecoder(),
846
- (compiledTransaction) => decompileTransaction(compiledTransaction, lastValidBlockHeight)
882
+ (compiledTransaction) => decompileTransaction(compiledTransaction, config)
847
883
  );
848
884
  }
849
- function getTransactionCodec(lastValidBlockHeight) {
850
- return combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
885
+ function getTransactionCodec(config) {
886
+ return combineCodec(getTransactionEncoder(), getTransactionDecoder(config));
851
887
  }
852
888
  var base58Decoder;
853
889
  function getSignatureFromTransaction(transaction) {
@@ -855,9 +891,7 @@ function getSignatureFromTransaction(transaction) {
855
891
  base58Decoder = getBase58Decoder();
856
892
  const signatureBytes = transaction.signatures[transaction.feePayer];
857
893
  if (!signatureBytes) {
858
- throw new Error(
859
- "Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
860
- );
894
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION_SIGNATURE_NOT_COMPUTABLE);
861
895
  }
862
896
  const transactionSignature = base58Decoder.decode(signatureBytes);
863
897
  return transactionSignature;
@@ -890,17 +924,23 @@ async function signTransaction(keyPairs, transaction) {
890
924
  function assertTransactionIsFullySigned(transaction) {
891
925
  const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
892
926
  const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
927
+ const missingSigs = [];
893
928
  requiredSigners.forEach((address) => {
894
929
  if (!transaction.signatures[address]) {
895
- throw new Error(`Transaction is missing signature for address \`${address}\``);
930
+ missingSigs.push(address);
896
931
  }
897
932
  });
933
+ if (missingSigs.length > 0) {
934
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_SIGNATURES, {
935
+ addresses: missingSigs
936
+ });
937
+ }
898
938
  }
899
939
  function getBase64EncodedWireTransaction(transaction) {
900
940
  const wireTransactionBytes = getTransactionEncoder().encode(transaction);
901
941
  return getBase64Decoder().decode(wireTransactionBytes);
902
942
  }
903
943
 
904
- export { appendTransactionInstruction, assertIsBlockhash, assertIsDurableNonceTransaction, assertIsTransactionWithBlockhashLifetime, assertTransactionIsFullySigned, compileMessage, createTransaction, getBase64EncodedWireTransaction, getCompiledMessageCodec, getCompiledMessageDecoder, getCompiledMessageEncoder, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, isAdvanceNonceAccountInstruction, partiallySignTransaction, prependTransactionInstruction, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, setTransactionLifetimeUsingDurableNonce, signTransaction };
944
+ 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
945
  //# sourceMappingURL=out.js.map
906
946
  //# sourceMappingURL=index.browser.js.map