@solana/transactions 2.0.0-experimental.ab12c29 → 2.0.0-experimental.ac2c1c8

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 (51) hide show
  1. package/README.md +7 -3
  2. package/dist/index.browser.cjs +301 -384
  3. package/dist/index.browser.cjs.map +1 -1
  4. package/dist/index.browser.js +300 -388
  5. package/dist/index.browser.js.map +1 -1
  6. package/dist/index.native.js +300 -388
  7. package/dist/index.native.js.map +1 -1
  8. package/dist/index.node.cjs +303 -384
  9. package/dist/index.node.cjs.map +1 -1
  10. package/dist/index.node.js +302 -388
  11. package/dist/index.node.js.map +1 -1
  12. package/dist/types/blockhash.d.ts +5 -7
  13. package/dist/types/blockhash.d.ts.map +1 -1
  14. package/dist/types/compilable-transaction.d.ts +4 -4
  15. package/dist/types/compile-address-table-lookups.d.ts +1 -1
  16. package/dist/types/compile-header.d.ts +1 -1
  17. package/dist/types/compile-instructions.d.ts +1 -1
  18. package/dist/types/compile-lifetime-token.d.ts +1 -1
  19. package/dist/types/compile-static-accounts.d.ts +1 -1
  20. package/dist/types/compile-transaction.d.ts +3 -3
  21. package/dist/types/create-transaction.d.ts +1 -1
  22. package/dist/types/decompile-transaction.d.ts +12 -4
  23. package/dist/types/decompile-transaction.d.ts.map +1 -1
  24. package/dist/types/durable-nonce.d.ts +2 -2
  25. package/dist/types/fee-payer.d.ts +2 -2
  26. package/dist/types/index.d.ts +13 -11
  27. package/dist/types/index.d.ts.map +1 -1
  28. package/dist/types/instructions.d.ts +4 -2
  29. package/dist/types/instructions.d.ts.map +1 -1
  30. package/dist/types/message.d.ts +6 -6
  31. package/dist/types/serializers/address-table-lookup.d.ts +5 -5
  32. package/dist/types/serializers/address-table-lookup.d.ts.map +1 -1
  33. package/dist/types/serializers/header.d.ts +5 -5
  34. package/dist/types/serializers/header.d.ts.map +1 -1
  35. package/dist/types/serializers/index.d.ts +2 -2
  36. package/dist/types/serializers/instruction.d.ts +5 -5
  37. package/dist/types/serializers/instruction.d.ts.map +1 -1
  38. package/dist/types/serializers/message.d.ts +5 -5
  39. package/dist/types/serializers/message.d.ts.map +1 -1
  40. package/dist/types/serializers/transaction-version.d.ts +5 -5
  41. package/dist/types/serializers/transaction-version.d.ts.map +1 -1
  42. package/dist/types/serializers/transaction.d.ts +9 -6
  43. package/dist/types/serializers/transaction.d.ts.map +1 -1
  44. package/dist/types/signatures.d.ts +2 -2
  45. package/dist/types/signatures.d.ts.map +1 -1
  46. package/dist/types/unsigned-transaction.d.ts +1 -1
  47. package/dist/types/wire-transaction.d.ts +1 -1
  48. package/package.json +18 -39
  49. package/dist/index.development.js +0 -1783
  50. package/dist/index.development.js.map +0 -1
  51. package/dist/index.production.min.js +0 -31
@@ -1,29 +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 { mapDecoder, combineCodec, mapEncoder } 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
- // ../build-scripts/env-shim.ts
10
- var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
11
-
12
- // src/unsigned-transaction.ts
13
- function getUnsignedTransaction(transaction) {
14
- if ("signatures" in transaction) {
15
- const {
16
- signatures: _,
17
- // eslint-disable-line @typescript-eslint/no-unused-vars
18
- ...unsignedTransaction
19
- } = transaction;
20
- return unsignedTransaction;
21
- } else {
22
- return transaction;
23
- }
24
- }
25
-
26
- // src/blockhash.ts
10
+ // ../rpc-types/dist/index.browser.js
27
11
  var base58Encoder;
28
12
  function assertIsBlockhash(putativeBlockhash) {
29
13
  if (!base58Encoder)
@@ -47,6 +31,38 @@ function assertIsBlockhash(putativeBlockhash) {
47
31
  });
48
32
  }
49
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
50
+ function isTransactionWithBlockhashLifetime(transaction) {
51
+ const lifetimeConstraintShapeMatches = "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.blockhash === "string" && typeof transaction.lifetimeConstraint.lastValidBlockHeight === "bigint";
52
+ if (!lifetimeConstraintShapeMatches)
53
+ return false;
54
+ try {
55
+ assertIsBlockhash(transaction.lifetimeConstraint.blockhash);
56
+ return true;
57
+ } catch {
58
+ return false;
59
+ }
60
+ }
61
+ function assertIsTransactionWithBlockhashLifetime(transaction) {
62
+ if (!isTransactionWithBlockhashLifetime(transaction)) {
63
+ throw new Error("Transaction does not have a blockhash lifetime");
64
+ }
65
+ }
50
66
  function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
51
67
  if ("lifetimeConstraint" in transaction && transaction.lifetimeConstraint.blockhash === blockhashLifetimeConstraint.blockhash && transaction.lifetimeConstraint.lastValidBlockHeight === blockhashLifetimeConstraint.lastValidBlockHeight) {
52
68
  return transaction;
@@ -185,21 +201,172 @@ function setTransactionFeePayer(feePayer, transaction) {
185
201
 
186
202
  // src/instructions.ts
187
203
  function appendTransactionInstruction(instruction, transaction) {
204
+ return appendTransactionInstructions([instruction], transaction);
205
+ }
206
+ function appendTransactionInstructions(instructions, transaction) {
188
207
  const out = {
189
208
  ...getUnsignedTransaction(transaction),
190
- instructions: [...transaction.instructions, instruction]
209
+ instructions: [...transaction.instructions, ...instructions]
191
210
  };
192
211
  Object.freeze(out);
193
212
  return out;
194
213
  }
195
214
  function prependTransactionInstruction(instruction, transaction) {
215
+ return prependTransactionInstructions([instruction], transaction);
216
+ }
217
+ function prependTransactionInstructions(instructions, transaction) {
196
218
  const out = {
197
219
  ...getUnsignedTransaction(transaction),
198
- instructions: [instruction, ...transaction.instructions]
220
+ instructions: [...instructions, ...transaction.instructions]
199
221
  };
200
222
  Object.freeze(out);
201
223
  return out;
202
224
  }
225
+
226
+ // src/decompile-transaction.ts
227
+ function getAccountMetas(message) {
228
+ const { header } = message;
229
+ const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
230
+ const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
231
+ const accountMetas = [];
232
+ let accountIndex = 0;
233
+ for (let i = 0; i < numWritableSignerAccounts; i++) {
234
+ accountMetas.push({
235
+ address: message.staticAccounts[accountIndex],
236
+ role: AccountRole.WRITABLE_SIGNER
237
+ });
238
+ accountIndex++;
239
+ }
240
+ for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
241
+ accountMetas.push({
242
+ address: message.staticAccounts[accountIndex],
243
+ role: AccountRole.READONLY_SIGNER
244
+ });
245
+ accountIndex++;
246
+ }
247
+ for (let i = 0; i < numWritableNonSignerAccounts; i++) {
248
+ accountMetas.push({
249
+ address: message.staticAccounts[accountIndex],
250
+ role: AccountRole.WRITABLE
251
+ });
252
+ accountIndex++;
253
+ }
254
+ for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
255
+ accountMetas.push({
256
+ address: message.staticAccounts[accountIndex],
257
+ role: AccountRole.READONLY
258
+ });
259
+ accountIndex++;
260
+ }
261
+ return accountMetas;
262
+ }
263
+ function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress) {
264
+ const compiledAddressTableLookupAddresses = compiledAddressTableLookups.map((l) => l.lookupTableAddress);
265
+ const missing = compiledAddressTableLookupAddresses.filter((a) => addressesByLookupTableAddress[a] === void 0);
266
+ if (missing.length > 0) {
267
+ const missingAddresses = missing.join(", ");
268
+ throw new Error(`Addresses not provided for lookup tables: [${missingAddresses}]`);
269
+ }
270
+ const readOnlyMetas = [];
271
+ const writableMetas = [];
272
+ for (const lookup of compiledAddressTableLookups) {
273
+ const addresses = addressesByLookupTableAddress[lookup.lookupTableAddress];
274
+ const highestIndex = Math.max(...lookup.readableIndices, ...lookup.writableIndices);
275
+ if (highestIndex >= addresses.length) {
276
+ throw new Error(
277
+ `Cannot look up index ${highestIndex} in lookup table [${lookup.lookupTableAddress}]. The lookup table may have been extended since the addresses provided were retrieved.`
278
+ );
279
+ }
280
+ const readOnlyForLookup = lookup.readableIndices.map((r) => ({
281
+ address: addresses[r],
282
+ addressIndex: r,
283
+ lookupTableAddress: lookup.lookupTableAddress,
284
+ role: AccountRole.READONLY
285
+ }));
286
+ readOnlyMetas.push(...readOnlyForLookup);
287
+ const writableForLookup = lookup.writableIndices.map((w) => ({
288
+ address: addresses[w],
289
+ addressIndex: w,
290
+ lookupTableAddress: lookup.lookupTableAddress,
291
+ role: AccountRole.WRITABLE
292
+ }));
293
+ writableMetas.push(...writableForLookup);
294
+ }
295
+ return [...writableMetas, ...readOnlyMetas];
296
+ }
297
+ function convertInstruction(instruction, accountMetas) {
298
+ const programAddress = accountMetas[instruction.programAddressIndex]?.address;
299
+ if (!programAddress) {
300
+ throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
301
+ }
302
+ const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
303
+ const { data } = instruction;
304
+ return {
305
+ programAddress,
306
+ ...accounts && accounts.length ? { accounts } : {},
307
+ ...data && data.length ? { data } : {}
308
+ };
309
+ }
310
+ function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
311
+ if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
312
+ return {
313
+ blockhash: messageLifetimeToken,
314
+ lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
315
+ // U64 MAX
316
+ };
317
+ } else {
318
+ const nonceAccountAddress = firstInstruction.accounts[0].address;
319
+ assertIsAddress(nonceAccountAddress);
320
+ const nonceAuthorityAddress = firstInstruction.accounts[2].address;
321
+ assertIsAddress(nonceAuthorityAddress);
322
+ return {
323
+ nonce: messageLifetimeToken,
324
+ nonceAccountAddress,
325
+ nonceAuthorityAddress
326
+ };
327
+ }
328
+ }
329
+ function convertSignatures(compiledTransaction) {
330
+ const {
331
+ compiledMessage: { staticAccounts },
332
+ signatures
333
+ } = compiledTransaction;
334
+ return signatures.reduce((acc, sig, index) => {
335
+ const allZeros = sig.every((byte) => byte === 0);
336
+ if (allZeros)
337
+ return acc;
338
+ const address = staticAccounts[index];
339
+ return { ...acc, [address]: sig };
340
+ }, {});
341
+ }
342
+ function decompileTransaction(compiledTransaction, config) {
343
+ const { compiledMessage } = compiledTransaction;
344
+ const feePayer = compiledMessage.staticAccounts[0];
345
+ if (!feePayer)
346
+ throw new Error("No fee payer set in CompiledTransaction");
347
+ const accountMetas = getAccountMetas(compiledMessage);
348
+ const accountLookupMetas = "addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups !== void 0 && compiledMessage.addressTableLookups.length > 0 ? getAddressLookupMetas(compiledMessage.addressTableLookups, config?.addressesByLookupTableAddress ?? {}) : [];
349
+ const transactionMetas = [...accountMetas, ...accountLookupMetas];
350
+ const instructions = compiledMessage.instructions.map(
351
+ (compiledInstruction) => convertInstruction(compiledInstruction, transactionMetas)
352
+ );
353
+ const firstInstruction = instructions[0];
354
+ const lifetimeConstraint = getLifetimeConstraint(
355
+ compiledMessage.lifetimeToken,
356
+ firstInstruction,
357
+ config?.lastValidBlockHeight
358
+ );
359
+ const signatures = convertSignatures(compiledTransaction);
360
+ return pipe(
361
+ createTransaction({ version: compiledMessage.version }),
362
+ (tx) => setTransactionFeePayer(feePayer, tx),
363
+ (tx) => instructions.reduce((acc, instruction) => {
364
+ return appendTransactionInstruction(instruction, acc);
365
+ }, tx),
366
+ (tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
367
+ (tx) => Object.keys(signatures).length > 0 ? { ...tx, signatures } : tx
368
+ );
369
+ }
203
370
  function upsert(addressMap, address, update) {
204
371
  addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
205
372
  }
@@ -465,59 +632,31 @@ function compileMessage(transaction) {
465
632
  version: transaction.version
466
633
  };
467
634
  }
468
- var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
469
- var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
470
- var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
471
- var addressTableLookupDescription = __DEV__ ? "A pointer to the address of an address lookup table, along with the readonly/writeable indices of the addresses that should be loaded from it" : "addressTableLookup";
472
635
  var memoizedAddressTableLookupEncoder;
473
636
  function getAddressTableLookupEncoder() {
474
637
  if (!memoizedAddressTableLookupEncoder) {
475
- memoizedAddressTableLookupEncoder = getStructEncoder(
638
+ memoizedAddressTableLookupEncoder = getStructEncoder([
639
+ ["lookupTableAddress", getAddressEncoder()],
476
640
  [
477
- ["lookupTableAddress", getAddressEncoder({ description: lookupTableAddressDescription })],
478
- [
479
- "writableIndices",
480
- getArrayEncoder(getU8Encoder(), {
481
- description: writableIndicesDescription,
482
- size: getShortU16Encoder()
483
- })
484
- ],
485
- [
486
- "readableIndices",
487
- getArrayEncoder(getU8Encoder(), {
488
- description: readableIndicesDescription,
489
- size: getShortU16Encoder()
490
- })
491
- ]
641
+ "writableIndices",
642
+ getArrayEncoder(getU8Encoder(), { size: getShortU16Encoder() })
492
643
  ],
493
- { description: addressTableLookupDescription }
494
- );
644
+ [
645
+ "readableIndices",
646
+ getArrayEncoder(getU8Encoder(), { size: getShortU16Encoder() })
647
+ ]
648
+ ]);
495
649
  }
496
650
  return memoizedAddressTableLookupEncoder;
497
651
  }
498
652
  var memoizedAddressTableLookupDecoder;
499
653
  function getAddressTableLookupDecoder() {
500
654
  if (!memoizedAddressTableLookupDecoder) {
501
- memoizedAddressTableLookupDecoder = getStructDecoder(
502
- [
503
- ["lookupTableAddress", getAddressDecoder({ description: lookupTableAddressDescription })],
504
- [
505
- "writableIndices",
506
- getArrayDecoder(getU8Decoder(), {
507
- description: writableIndicesDescription,
508
- size: getShortU16Decoder()
509
- })
510
- ],
511
- [
512
- "readableIndices",
513
- getArrayDecoder(getU8Decoder(), {
514
- description: readableIndicesDescription,
515
- size: getShortU16Decoder()
516
- })
517
- ]
518
- ],
519
- { description: addressTableLookupDescription }
520
- );
655
+ memoizedAddressTableLookupDecoder = getStructDecoder([
656
+ ["lookupTableAddress", getAddressDecoder()],
657
+ ["writableIndices", getArrayDecoder(getU8Decoder(), { size: getShortU16Decoder() })],
658
+ ["readableIndices", getArrayDecoder(getU8Decoder(), { size: getShortU16Decoder() })]
659
+ ]);
521
660
  }
522
661
  return memoizedAddressTableLookupDecoder;
523
662
  }
@@ -527,72 +666,34 @@ function getMemoizedU8Encoder() {
527
666
  memoizedU8Encoder = getU8Encoder();
528
667
  return memoizedU8Encoder;
529
668
  }
530
- function getMemoizedU8EncoderDescription(description) {
531
- const encoder = getMemoizedU8Encoder();
532
- return {
533
- ...encoder,
534
- description: description ?? encoder.description
535
- };
536
- }
537
669
  var memoizedU8Decoder;
538
670
  function getMemoizedU8Decoder() {
539
671
  if (!memoizedU8Decoder)
540
672
  memoizedU8Decoder = getU8Decoder();
541
673
  return memoizedU8Decoder;
542
674
  }
543
- function getMemoizedU8DecoderDescription(description) {
544
- const decoder = getMemoizedU8Decoder();
545
- return {
546
- ...decoder,
547
- description: description ?? decoder.description
548
- };
549
- }
550
- 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;
551
- 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;
552
- var numReadonlyNonSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable" : void 0;
553
- var messageHeaderDescription = __DEV__ ? "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses" : void 0;
554
675
  function getMessageHeaderEncoder() {
555
- return getStructEncoder(
556
- [
557
- ["numSignerAccounts", getMemoizedU8EncoderDescription(numSignerAccountsDescription)],
558
- ["numReadonlySignerAccounts", getMemoizedU8EncoderDescription(numReadonlySignerAccountsDescription)],
559
- ["numReadonlyNonSignerAccounts", getMemoizedU8EncoderDescription(numReadonlyNonSignerAccountsDescription)]
560
- ],
561
- {
562
- description: messageHeaderDescription
563
- }
564
- );
676
+ return getStructEncoder([
677
+ ["numSignerAccounts", getMemoizedU8Encoder()],
678
+ ["numReadonlySignerAccounts", getMemoizedU8Encoder()],
679
+ ["numReadonlyNonSignerAccounts", getMemoizedU8Encoder()]
680
+ ]);
565
681
  }
566
682
  function getMessageHeaderDecoder() {
567
- return getStructDecoder(
568
- [
569
- ["numSignerAccounts", getMemoizedU8DecoderDescription(numSignerAccountsDescription)],
570
- ["numReadonlySignerAccounts", getMemoizedU8DecoderDescription(numReadonlySignerAccountsDescription)],
571
- ["numReadonlyNonSignerAccounts", getMemoizedU8DecoderDescription(numReadonlyNonSignerAccountsDescription)]
572
- ],
573
- {
574
- description: messageHeaderDescription
575
- }
576
- );
683
+ return getStructDecoder([
684
+ ["numSignerAccounts", getMemoizedU8Decoder()],
685
+ ["numReadonlySignerAccounts", getMemoizedU8Decoder()],
686
+ ["numReadonlyNonSignerAccounts", getMemoizedU8Decoder()]
687
+ ]);
577
688
  }
578
- var programAddressIndexDescription = __DEV__ ? "The index of the program being called, according to the well-ordered accounts list for this transaction" : "programAddressIndex";
579
- var accountIndexDescription = __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : void 0;
580
- var accountIndicesDescription = __DEV__ ? "An optional list of account indices, according to the well-ordered accounts list for this transaction, in the order in which the program being called expects them" : "accountIndices";
581
- var dataDescription = __DEV__ ? "An optional buffer of data passed to the instruction" : "data";
582
689
  var memoizedGetInstructionEncoder;
583
690
  function getInstructionEncoder() {
584
691
  if (!memoizedGetInstructionEncoder) {
585
692
  memoizedGetInstructionEncoder = mapEncoder(
586
693
  getStructEncoder([
587
- ["programAddressIndex", getU8Encoder({ description: programAddressIndexDescription })],
588
- [
589
- "accountIndices",
590
- getArrayEncoder(getU8Encoder({ description: accountIndexDescription }), {
591
- description: accountIndicesDescription,
592
- size: getShortU16Encoder()
593
- })
594
- ],
595
- ["data", getBytesEncoder({ description: dataDescription, size: getShortU16Encoder() })]
694
+ ["programAddressIndex", getU8Encoder()],
695
+ ["accountIndices", getArrayEncoder(getU8Encoder(), { size: getShortU16Encoder() })],
696
+ ["data", getBytesEncoder({ size: getShortU16Encoder() })]
596
697
  ]),
597
698
  // Convert an instruction to have all fields defined
598
699
  (instruction) => {
@@ -614,15 +715,9 @@ function getInstructionDecoder() {
614
715
  if (!memoizedGetInstructionDecoder) {
615
716
  memoizedGetInstructionDecoder = mapDecoder(
616
717
  getStructDecoder([
617
- ["programAddressIndex", getU8Decoder({ description: programAddressIndexDescription })],
618
- [
619
- "accountIndices",
620
- getArrayDecoder(getU8Decoder({ description: accountIndexDescription }), {
621
- description: accountIndicesDescription,
622
- size: getShortU16Decoder()
623
- })
624
- ],
625
- ["data", getBytesDecoder({ description: dataDescription, size: getShortU16Decoder() })]
718
+ ["programAddressIndex", getU8Decoder()],
719
+ ["accountIndices", getArrayDecoder(getU8Decoder(), { size: getShortU16Decoder() })],
720
+ ["data", getBytesDecoder({ size: getShortU16Decoder() })]
626
721
  ]),
627
722
  // Convert an instruction to exclude optional fields if they are empty
628
723
  (instruction) => {
@@ -641,47 +736,38 @@ function getInstructionDecoder() {
641
736
  return memoizedGetInstructionDecoder;
642
737
  }
643
738
  var VERSION_FLAG_MASK = 128;
644
- var BASE_CONFIG = {
645
- description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
646
- fixedSize: null,
647
- maxSize: 1
648
- };
649
- function decode(bytes, offset = 0) {
650
- const firstByte = bytes[offset];
651
- if ((firstByte & VERSION_FLAG_MASK) === 0) {
652
- return ["legacy", offset];
653
- } else {
654
- const version = firstByte ^ VERSION_FLAG_MASK;
655
- return [version, offset + 1];
656
- }
657
- }
658
- function encode(value) {
659
- if (value === "legacy") {
660
- return new Uint8Array();
661
- }
662
- if (value < 0 || value > 127) {
663
- throw new Error(`Transaction version must be in the range [0, 127]. \`${value}\` given.`);
664
- }
665
- return new Uint8Array([value | VERSION_FLAG_MASK]);
739
+ function getTransactionVersionEncoder() {
740
+ return createEncoder({
741
+ getSizeFromValue: (value) => value === "legacy" ? 0 : 1,
742
+ maxSize: 1,
743
+ write: (value, bytes, offset) => {
744
+ if (value === "legacy") {
745
+ return offset;
746
+ }
747
+ if (value < 0 || value > 127) {
748
+ throw new Error(`Transaction version must be in the range [0, 127]. \`${value}\` given.`);
749
+ }
750
+ bytes.set([value | VERSION_FLAG_MASK], offset);
751
+ return offset + 1;
752
+ }
753
+ });
666
754
  }
667
755
  function getTransactionVersionDecoder() {
668
- return {
669
- ...BASE_CONFIG,
670
- decode
671
- };
672
- }
673
- function getTransactionVersionEncoder() {
674
- return {
675
- ...BASE_CONFIG,
676
- encode
677
- };
756
+ return createDecoder({
757
+ maxSize: 1,
758
+ read: (bytes, offset) => {
759
+ const firstByte = bytes[offset];
760
+ if ((firstByte & VERSION_FLAG_MASK) === 0) {
761
+ return ["legacy", offset];
762
+ } else {
763
+ const version = firstByte ^ VERSION_FLAG_MASK;
764
+ return [version, offset + 1];
765
+ }
766
+ }
767
+ });
678
768
  }
679
769
 
680
770
  // src/serializers/message.ts
681
- var staticAccountsDescription = __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "staticAccounts";
682
- var lifetimeTokenDescription = __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "lifetimeToken";
683
- var instructionsDescription = __DEV__ ? "A compact-array of instructions belonging to this transaction" : "instructions";
684
- var addressTableLookupsDescription = __DEV__ ? "A compact array of address table lookups belonging to this transaction" : "addressTableLookups";
685
771
  function getCompiledMessageLegacyEncoder() {
686
772
  return getStructEncoder(getPreludeStructEncoderTuple());
687
773
  }
@@ -706,98 +792,52 @@ function getPreludeStructEncoderTuple() {
706
792
  return [
707
793
  ["version", getTransactionVersionEncoder()],
708
794
  ["header", getMessageHeaderEncoder()],
709
- [
710
- "staticAccounts",
711
- getArrayEncoder(getAddressEncoder(), {
712
- description: staticAccountsDescription,
713
- size: getShortU16Encoder()
714
- })
715
- ],
716
- [
717
- "lifetimeToken",
718
- getStringEncoder({
719
- description: lifetimeTokenDescription,
720
- encoding: getBase58Encoder(),
721
- size: 32
722
- })
723
- ],
724
- [
725
- "instructions",
726
- getArrayEncoder(getInstructionEncoder(), {
727
- description: instructionsDescription,
728
- size: getShortU16Encoder()
729
- })
730
- ]
795
+ ["staticAccounts", getArrayEncoder(getAddressEncoder(), { size: getShortU16Encoder() })],
796
+ ["lifetimeToken", getStringEncoder({ encoding: getBase58Encoder(), size: 32 })],
797
+ ["instructions", getArrayEncoder(getInstructionEncoder(), { size: getShortU16Encoder() })]
731
798
  ];
732
799
  }
733
800
  function getPreludeStructDecoderTuple() {
734
801
  return [
735
802
  ["version", getTransactionVersionDecoder()],
736
803
  ["header", getMessageHeaderDecoder()],
737
- [
738
- "staticAccounts",
739
- getArrayDecoder(getAddressDecoder(), {
740
- description: staticAccountsDescription,
741
- size: getShortU16Decoder()
742
- })
743
- ],
744
- [
745
- "lifetimeToken",
746
- getStringDecoder({
747
- description: lifetimeTokenDescription,
748
- encoding: getBase58Decoder(),
749
- size: 32
750
- })
751
- ],
752
- [
753
- "instructions",
754
- getArrayDecoder(getInstructionDecoder(), {
755
- description: instructionsDescription,
756
- size: getShortU16Decoder()
757
- })
758
- ],
804
+ ["staticAccounts", getArrayDecoder(getAddressDecoder(), { size: getShortU16Decoder() })],
805
+ ["lifetimeToken", getStringDecoder({ encoding: getBase58Decoder(), size: 32 })],
806
+ ["instructions", getArrayDecoder(getInstructionDecoder(), { size: getShortU16Decoder() })],
759
807
  ["addressTableLookups", getAddressTableLookupArrayDecoder()]
760
808
  ];
761
809
  }
762
810
  function getAddressTableLookupArrayEncoder() {
763
- return getArrayEncoder(getAddressTableLookupEncoder(), {
764
- description: addressTableLookupsDescription,
765
- size: getShortU16Encoder()
766
- });
811
+ return getArrayEncoder(getAddressTableLookupEncoder(), { size: getShortU16Encoder() });
767
812
  }
768
813
  function getAddressTableLookupArrayDecoder() {
769
- return getArrayDecoder(getAddressTableLookupDecoder(), {
770
- description: addressTableLookupsDescription,
771
- size: getShortU16Decoder()
772
- });
814
+ return getArrayDecoder(getAddressTableLookupDecoder(), { size: getShortU16Decoder() });
773
815
  }
774
- var messageDescription = __DEV__ ? "The wire format of a Solana transaction message" : "message";
775
816
  function getCompiledMessageEncoder() {
776
- return {
777
- description: messageDescription,
778
- encode: (compiledMessage) => {
817
+ return createEncoder({
818
+ getSizeFromValue: (compiledMessage) => {
779
819
  if (compiledMessage.version === "legacy") {
780
- return getCompiledMessageLegacyEncoder().encode(compiledMessage);
820
+ return getCompiledMessageLegacyEncoder().getSizeFromValue(compiledMessage);
781
821
  } else {
782
- return getCompiledMessageVersionedEncoder().encode(compiledMessage);
822
+ return getCompiledMessageVersionedEncoder().getSizeFromValue(compiledMessage);
783
823
  }
784
824
  },
785
- fixedSize: null,
786
- maxSize: null
787
- };
825
+ write: (compiledMessage, bytes, offset) => {
826
+ if (compiledMessage.version === "legacy") {
827
+ return getCompiledMessageLegacyEncoder().write(compiledMessage, bytes, offset);
828
+ } else {
829
+ return getCompiledMessageVersionedEncoder().write(compiledMessage, bytes, offset);
830
+ }
831
+ }
832
+ });
788
833
  }
789
834
  function getCompiledMessageDecoder() {
790
- return mapDecoder(
791
- getStructDecoder(getPreludeStructDecoderTuple(), {
792
- description: messageDescription
793
- }),
794
- ({ addressTableLookups, ...restOfMessage }) => {
795
- if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
796
- return restOfMessage;
797
- }
798
- return { ...restOfMessage, addressTableLookups };
835
+ return mapDecoder(getStructDecoder(getPreludeStructDecoderTuple()), ({ addressTableLookups, ...restOfMessage }) => {
836
+ if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
837
+ return restOfMessage;
799
838
  }
800
- );
839
+ return { ...restOfMessage, addressTableLookups };
840
+ });
801
841
  }
802
842
  function getCompiledMessageCodec() {
803
843
  return combineCodec(getCompiledMessageEncoder(), getCompiledMessageDecoder());
@@ -820,168 +860,36 @@ function getCompiledTransaction(transaction) {
820
860
  signatures
821
861
  };
822
862
  }
823
- function getAccountMetas(message) {
824
- const { header } = message;
825
- const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
826
- const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
827
- const accountMetas = [];
828
- let accountIndex = 0;
829
- for (let i = 0; i < numWritableSignerAccounts; i++) {
830
- accountMetas.push({
831
- address: message.staticAccounts[accountIndex],
832
- role: AccountRole.WRITABLE_SIGNER
833
- });
834
- accountIndex++;
835
- }
836
- for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
837
- accountMetas.push({
838
- address: message.staticAccounts[accountIndex],
839
- role: AccountRole.READONLY_SIGNER
840
- });
841
- accountIndex++;
842
- }
843
- for (let i = 0; i < numWritableNonSignerAccounts; i++) {
844
- accountMetas.push({
845
- address: message.staticAccounts[accountIndex],
846
- role: AccountRole.WRITABLE
847
- });
848
- accountIndex++;
849
- }
850
- for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
851
- accountMetas.push({
852
- address: message.staticAccounts[accountIndex],
853
- role: AccountRole.READONLY
854
- });
855
- accountIndex++;
856
- }
857
- return accountMetas;
858
- }
859
- function convertInstruction(instruction, accountMetas) {
860
- const programAddress = accountMetas[instruction.programAddressIndex]?.address;
861
- if (!programAddress) {
862
- throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
863
- }
864
- const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
865
- const { data } = instruction;
866
- return {
867
- programAddress,
868
- ...accounts && accounts.length ? { accounts } : {},
869
- ...data && data.length ? { data } : {}
870
- };
871
- }
872
- function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
873
- if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
874
- return {
875
- blockhash: messageLifetimeToken,
876
- lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
877
- // U64 MAX
878
- };
879
- } else {
880
- const nonceAccountAddress = firstInstruction.accounts[0].address;
881
- assertIsAddress(nonceAccountAddress);
882
- const nonceAuthorityAddress = firstInstruction.accounts[2].address;
883
- assertIsAddress(nonceAuthorityAddress);
884
- return {
885
- nonce: messageLifetimeToken,
886
- nonceAccountAddress,
887
- nonceAuthorityAddress
888
- };
889
- }
890
- }
891
- function convertSignatures(compiledTransaction) {
892
- const {
893
- compiledMessage: { staticAccounts },
894
- signatures
895
- } = compiledTransaction;
896
- return signatures.reduce((acc, sig, index) => {
897
- const allZeros = sig.every((byte) => byte === 0);
898
- if (allZeros)
899
- return acc;
900
- const address = staticAccounts[index];
901
- return { ...acc, [address]: sig };
902
- }, {});
903
- }
904
- function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
905
- const { compiledMessage } = compiledTransaction;
906
- if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
907
- throw new Error("Cannot convert transaction with addressTableLookups");
908
- }
909
- const feePayer = compiledMessage.staticAccounts[0];
910
- if (!feePayer)
911
- throw new Error("No fee payer set in CompiledTransaction");
912
- const accountMetas = getAccountMetas(compiledMessage);
913
- const instructions = compiledMessage.instructions.map(
914
- (compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
915
- );
916
- const firstInstruction = instructions[0];
917
- const lifetimeConstraint = getLifetimeConstraint(
918
- compiledMessage.lifetimeToken,
919
- firstInstruction,
920
- lastValidBlockHeight
921
- );
922
- const signatures = convertSignatures(compiledTransaction);
923
- return pipe(
924
- createTransaction({ version: compiledMessage.version }),
925
- (tx) => setTransactionFeePayer(feePayer, tx),
926
- (tx) => instructions.reduce((acc, instruction) => {
927
- return appendTransactionInstruction(instruction, acc);
928
- }, tx),
929
- (tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
930
- (tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
931
- );
932
- }
933
863
 
934
864
  // src/serializers/transaction.ts
935
- var signaturesDescription = __DEV__ ? "A compact array of 64-byte, base-64 encoded Ed25519 signatures" : "signatures";
936
- var transactionDescription = __DEV__ ? "The wire format of a Solana transaction" : "transaction";
937
865
  function getCompiledTransactionEncoder() {
938
- return getStructEncoder(
939
- [
940
- [
941
- "signatures",
942
- getArrayEncoder(getBytesEncoder({ size: 64 }), {
943
- description: signaturesDescription,
944
- size: getShortU16Encoder()
945
- })
946
- ],
947
- ["compiledMessage", getCompiledMessageEncoder()]
948
- ],
949
- {
950
- description: transactionDescription
951
- }
952
- );
953
- }
954
- function getSignatureDecoder() {
955
- return mapDecoder(getBytesDecoder({ size: 64 }), (bytes) => bytes);
866
+ return getStructEncoder([
867
+ ["signatures", getArrayEncoder(getBytesEncoder({ size: 64 }), { size: getShortU16Encoder() })],
868
+ ["compiledMessage", getCompiledMessageEncoder()]
869
+ ]);
956
870
  }
957
871
  function getCompiledTransactionDecoder() {
958
- return getStructDecoder(
872
+ return getStructDecoder([
959
873
  [
960
- [
961
- "signatures",
962
- getArrayDecoder(getSignatureDecoder(), {
963
- description: signaturesDescription,
964
- size: getShortU16Decoder()
965
- })
966
- ],
967
- ["compiledMessage", getCompiledMessageDecoder()]
874
+ "signatures",
875
+ getArrayDecoder(getBytesDecoder({ size: 64 }), {
876
+ size: getShortU16Decoder()
877
+ })
968
878
  ],
969
- {
970
- description: transactionDescription
971
- }
972
- );
879
+ ["compiledMessage", getCompiledMessageDecoder()]
880
+ ]);
973
881
  }
974
882
  function getTransactionEncoder() {
975
883
  return mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
976
884
  }
977
- function getTransactionDecoder(lastValidBlockHeight) {
885
+ function getTransactionDecoder(config) {
978
886
  return mapDecoder(
979
887
  getCompiledTransactionDecoder(),
980
- (compiledTransaction) => decompileTransaction(compiledTransaction, lastValidBlockHeight)
888
+ (compiledTransaction) => decompileTransaction(compiledTransaction, config)
981
889
  );
982
890
  }
983
- function getTransactionCodec(lastValidBlockHeight) {
984
- return combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
891
+ function getTransactionCodec(config) {
892
+ return combineCodec(getTransactionEncoder(), getTransactionDecoder(config));
985
893
  }
986
894
  var base58Decoder;
987
895
  function getSignatureFromTransaction(transaction) {
@@ -989,11 +897,9 @@ function getSignatureFromTransaction(transaction) {
989
897
  base58Decoder = getBase58Decoder();
990
898
  const signatureBytes = transaction.signatures[transaction.feePayer];
991
899
  if (!signatureBytes) {
992
- throw new Error(
993
- "Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
994
- );
900
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION_SIGNATURE_NOT_COMPUTABLE);
995
901
  }
996
- const transactionSignature = base58Decoder.decode(signatureBytes)[0];
902
+ const transactionSignature = base58Decoder.decode(signatureBytes);
997
903
  return transactionSignature;
998
904
  }
999
905
  async function partiallySignTransaction(keyPairs, transaction) {
@@ -1024,17 +930,23 @@ async function signTransaction(keyPairs, transaction) {
1024
930
  function assertTransactionIsFullySigned(transaction) {
1025
931
  const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
1026
932
  const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
933
+ const missingSigs = [];
1027
934
  requiredSigners.forEach((address) => {
1028
935
  if (!transaction.signatures[address]) {
1029
- throw new Error(`Transaction is missing signature for address \`${address}\``);
936
+ missingSigs.push(address);
1030
937
  }
1031
938
  });
939
+ if (missingSigs.length > 0) {
940
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_SIGNATURES, {
941
+ addresses: missingSigs
942
+ });
943
+ }
1032
944
  }
1033
945
  function getBase64EncodedWireTransaction(transaction) {
1034
946
  const wireTransactionBytes = getTransactionEncoder().encode(transaction);
1035
- return getBase64Decoder().decode(wireTransactionBytes)[0];
947
+ return getBase64Decoder().decode(wireTransactionBytes);
1036
948
  }
1037
949
 
1038
- export { appendTransactionInstruction, assertIsBlockhash, assertIsDurableNonceTransaction, assertTransactionIsFullySigned, compileMessage, createTransaction, getBase64EncodedWireTransaction, getCompiledMessageCodec, getCompiledMessageDecoder, getCompiledMessageEncoder, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, isAdvanceNonceAccountInstruction, partiallySignTransaction, prependTransactionInstruction, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, setTransactionLifetimeUsingDurableNonce, signTransaction };
950
+ export { appendTransactionInstruction, appendTransactionInstructions, assertIsDurableNonceTransaction, assertIsTransactionWithBlockhashLifetime, assertTransactionIsFullySigned, compileMessage, createTransaction, decompileTransaction, getBase64EncodedWireTransaction, getCompiledMessageCodec, getCompiledMessageDecoder, getCompiledMessageEncoder, getCompiledTransactionDecoder, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, getUnsignedTransaction, isAdvanceNonceAccountInstruction, partiallySignTransaction, prependTransactionInstruction, prependTransactionInstructions, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, setTransactionLifetimeUsingDurableNonce, signTransaction };
1039
951
  //# sourceMappingURL=out.js.map
1040
952
  //# sourceMappingURL=index.browser.js.map