@solana/transactions 2.0.0-experimental.cc94aa3 → 2.0.0-experimental.ccd92fd

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