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