@solana/transactions 2.0.0-experimental.0de6c3e → 2.0.0-experimental.0eb69ae

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 (64) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +272 -5
  3. package/dist/index.browser.cjs +650 -281
  4. package/dist/index.browser.cjs.map +1 -1
  5. package/dist/index.browser.js +637 -281
  6. package/dist/index.browser.js.map +1 -1
  7. package/dist/index.development.js +1317 -776
  8. package/dist/index.development.js.map +1 -1
  9. package/dist/index.native.js +637 -281
  10. package/dist/index.native.js.map +1 -1
  11. package/dist/index.node.cjs +652 -279
  12. package/dist/index.node.cjs.map +1 -1
  13. package/dist/index.node.js +637 -281
  14. package/dist/index.node.js.map +1 -1
  15. package/dist/index.production.min.js +22 -7
  16. package/dist/types/accounts.d.ts +3 -3
  17. package/dist/types/blockhash.d.ts +9 -1
  18. package/dist/types/compilable-transaction.d.ts +7 -0
  19. package/dist/types/compile-address-table-lookups.d.ts +2 -2
  20. package/dist/types/compile-instructions.d.ts +1 -1
  21. package/dist/types/compile-static-accounts.d.ts +2 -2
  22. package/dist/types/compile-transaction.d.ts +5 -6
  23. package/dist/types/decompile-transaction.d.ts +5 -0
  24. package/dist/types/durable-nonce.d.ts +23 -10
  25. package/dist/types/fee-payer.d.ts +4 -3
  26. package/dist/types/index.d.ts +3 -0
  27. package/dist/types/message.d.ts +1 -5
  28. package/dist/types/serializers/address-table-lookup.d.ts +5 -3
  29. package/dist/types/serializers/header.d.ts +4 -2
  30. package/dist/types/serializers/index.d.ts +3 -0
  31. package/dist/types/serializers/instruction.d.ts +4 -2
  32. package/dist/types/serializers/message.d.ts +4 -4
  33. package/dist/types/serializers/transaction-version.d.ts +4 -4
  34. package/dist/types/serializers/transaction.d.ts +6 -5
  35. package/dist/types/signatures.d.ts +10 -7
  36. package/dist/types/types.d.ts +13 -13
  37. package/dist/types/unsigned-transaction.d.ts +4 -0
  38. package/dist/types/wire-transaction.d.ts +2 -2
  39. package/package.json +24 -22
  40. package/dist/types/accounts.d.ts.map +0 -1
  41. package/dist/types/blockhash.d.ts.map +0 -1
  42. package/dist/types/compile-address-table-lookups.d.ts.map +0 -1
  43. package/dist/types/compile-header.d.ts.map +0 -1
  44. package/dist/types/compile-instructions.d.ts.map +0 -1
  45. package/dist/types/compile-lifetime-token.d.ts.map +0 -1
  46. package/dist/types/compile-static-accounts.d.ts.map +0 -1
  47. package/dist/types/compile-transaction.d.ts.map +0 -1
  48. package/dist/types/create-transaction.d.ts.map +0 -1
  49. package/dist/types/durable-nonce.d.ts.map +0 -1
  50. package/dist/types/fee-payer.d.ts.map +0 -1
  51. package/dist/types/index.d.ts.map +0 -1
  52. package/dist/types/instructions.d.ts.map +0 -1
  53. package/dist/types/message.d.ts.map +0 -1
  54. package/dist/types/serializers/address-table-lookup.d.ts.map +0 -1
  55. package/dist/types/serializers/header.d.ts.map +0 -1
  56. package/dist/types/serializers/instruction.d.ts.map +0 -1
  57. package/dist/types/serializers/message.d.ts.map +0 -1
  58. package/dist/types/serializers/transaction-version.d.ts.map +0 -1
  59. package/dist/types/serializers/transaction.d.ts.map +0 -1
  60. package/dist/types/serializers/unimplemented.d.ts +0 -3
  61. package/dist/types/serializers/unimplemented.d.ts.map +0 -1
  62. package/dist/types/signatures.d.ts.map +0 -1
  63. package/dist/types/types.d.ts.map +0 -1
  64. package/dist/types/wire-transaction.d.ts.map +0 -1
@@ -1,79 +1,74 @@
1
1
  'use strict';
2
2
 
3
+ var codecsStrings = require('@solana/codecs-strings');
4
+ var addresses = require('@solana/addresses');
5
+ var codecsCore = require('@solana/codecs-core');
6
+ var codecsDataStructures = require('@solana/codecs-data-structures');
7
+ var codecsNumbers = require('@solana/codecs-numbers');
8
+ var functional = require('@solana/functional');
3
9
  var keys = require('@solana/keys');
4
- var umiSerializers = require('@metaplex-foundation/umi-serializers');
5
10
 
6
11
  // ../build-scripts/env-shim.ts
7
12
  var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
8
13
 
9
- // src/create-transaction.ts
10
- function createTransaction({
11
- version
12
- }) {
13
- const out = {
14
- instructions: [],
15
- version
16
- };
17
- Object.freeze(out);
18
- return out;
19
- }
20
-
21
- // src/fee-payer.ts
22
- function setTransactionFeePayer(feePayer, transaction) {
23
- if ("feePayer" in transaction && feePayer === transaction.feePayer) {
24
- return transaction;
25
- }
26
- let out;
14
+ // src/unsigned-transaction.ts
15
+ function getUnsignedTransaction(transaction) {
27
16
  if ("signatures" in transaction) {
28
17
  const {
29
18
  signatures: _,
30
19
  // eslint-disable-line @typescript-eslint/no-unused-vars
31
20
  ...unsignedTransaction
32
21
  } = transaction;
33
- out = {
34
- ...unsignedTransaction,
35
- feePayer
36
- };
22
+ return unsignedTransaction;
37
23
  } else {
38
- out = {
39
- ...transaction,
40
- feePayer
41
- };
24
+ return transaction;
42
25
  }
43
- Object.freeze(out);
44
- return out;
45
26
  }
46
27
 
47
- // src/instructions.ts
48
- function replaceInstructions(transaction, nextInstructions) {
49
- let out;
50
- if ("signatures" in transaction) {
51
- const {
52
- signatures: _,
53
- // eslint-disable-line @typescript-eslint/no-unused-vars
54
- ...unsignedTransaction
55
- } = transaction;
56
- out = {
57
- ...unsignedTransaction,
58
- instructions: nextInstructions
59
- };
60
- } else {
61
- out = {
62
- ...transaction,
63
- instructions: nextInstructions
64
- };
28
+ // src/blockhash.ts
29
+ var base58Encoder;
30
+ function assertIsBlockhash(putativeBlockhash) {
31
+ if (!base58Encoder)
32
+ base58Encoder = codecsStrings.getBase58Encoder();
33
+ try {
34
+ if (
35
+ // Lowest value (32 bytes of zeroes)
36
+ putativeBlockhash.length < 32 || // Highest value (32 bytes of 255)
37
+ putativeBlockhash.length > 44
38
+ ) {
39
+ throw new Error("Expected input string to decode to a byte array of length 32.");
40
+ }
41
+ const bytes = base58Encoder.encode(putativeBlockhash);
42
+ const numBytes = bytes.byteLength;
43
+ if (numBytes !== 32) {
44
+ throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
45
+ }
46
+ } catch (e) {
47
+ throw new Error(`\`${putativeBlockhash}\` is not a blockhash`, {
48
+ cause: e
49
+ });
65
50
  }
66
- return out;
67
51
  }
68
- function appendTransactionInstruction(instruction, transaction) {
69
- const nextInstructions = [...transaction.instructions, instruction];
70
- const out = replaceInstructions(transaction, nextInstructions);
52
+ function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
53
+ if ("lifetimeConstraint" in transaction && transaction.lifetimeConstraint.blockhash === blockhashLifetimeConstraint.blockhash && transaction.lifetimeConstraint.lastValidBlockHeight === blockhashLifetimeConstraint.lastValidBlockHeight) {
54
+ return transaction;
55
+ }
56
+ const out = {
57
+ ...getUnsignedTransaction(transaction),
58
+ lifetimeConstraint: blockhashLifetimeConstraint
59
+ };
71
60
  Object.freeze(out);
72
61
  return out;
73
62
  }
74
- function prependTransactionInstruction(instruction, transaction) {
75
- const nextInstructions = [instruction, ...transaction.instructions];
76
- const out = replaceInstructions(transaction, nextInstructions);
63
+
64
+ // src/create-transaction.ts
65
+ function createTransaction({
66
+ version
67
+ }) {
68
+ const out = {
69
+ instructions: [],
70
+ version
71
+ };
77
72
  Object.freeze(out);
78
73
  return out;
79
74
  }
@@ -100,6 +95,113 @@ function isWritableRole(role) {
100
95
  function mergeRoles(roleA, roleB) {
101
96
  return roleA | roleB;
102
97
  }
98
+
99
+ // src/durable-nonce.ts
100
+ var RECENT_BLOCKHASHES_SYSVAR_ADDRESS = "SysvarRecentB1ockHashes11111111111111111111";
101
+ var SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
102
+ function assertIsDurableNonceTransaction(transaction) {
103
+ if (!isDurableNonceTransaction(transaction)) {
104
+ throw new Error("Transaction is not a durable nonce transaction");
105
+ }
106
+ }
107
+ function createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress) {
108
+ return {
109
+ accounts: [
110
+ { address: nonceAccountAddress, role: AccountRole.WRITABLE },
111
+ {
112
+ address: RECENT_BLOCKHASHES_SYSVAR_ADDRESS,
113
+ role: AccountRole.READONLY
114
+ },
115
+ { address: nonceAuthorityAddress, role: AccountRole.READONLY_SIGNER }
116
+ ],
117
+ data: new Uint8Array([4, 0, 0, 0]),
118
+ programAddress: SYSTEM_PROGRAM_ADDRESS
119
+ };
120
+ }
121
+ function isAdvanceNonceAccountInstruction(instruction) {
122
+ return instruction.programAddress === SYSTEM_PROGRAM_ADDRESS && // Test for `AdvanceNonceAccount` instruction data
123
+ instruction.data != null && isAdvanceNonceAccountInstructionData(instruction.data) && // Test for exactly 3 accounts
124
+ instruction.accounts?.length === 3 && // First account is nonce account address
125
+ instruction.accounts[0].address != null && instruction.accounts[0].role === AccountRole.WRITABLE && // Second account is recent blockhashes sysvar
126
+ instruction.accounts[1].address === RECENT_BLOCKHASHES_SYSVAR_ADDRESS && instruction.accounts[1].role === AccountRole.READONLY && // Third account is nonce authority account
127
+ instruction.accounts[2].address != null && isSignerRole(instruction.accounts[2].role);
128
+ }
129
+ function isAdvanceNonceAccountInstructionData(data) {
130
+ return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;
131
+ }
132
+ function isDurableNonceTransaction(transaction) {
133
+ return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
134
+ }
135
+ function isAdvanceNonceAccountInstructionForNonce(instruction, nonceAccountAddress, nonceAuthorityAddress) {
136
+ return instruction.accounts[0].address === nonceAccountAddress && instruction.accounts[2].address === nonceAuthorityAddress;
137
+ }
138
+ function setTransactionLifetimeUsingDurableNonce({
139
+ nonce,
140
+ nonceAccountAddress,
141
+ nonceAuthorityAddress
142
+ }, transaction) {
143
+ let newInstructions;
144
+ const firstInstruction = transaction.instructions[0];
145
+ if (firstInstruction && isAdvanceNonceAccountInstruction(firstInstruction)) {
146
+ if (isAdvanceNonceAccountInstructionForNonce(firstInstruction, nonceAccountAddress, nonceAuthorityAddress)) {
147
+ if (isDurableNonceTransaction(transaction) && transaction.lifetimeConstraint.nonce === nonce) {
148
+ return transaction;
149
+ } else {
150
+ newInstructions = [firstInstruction, ...transaction.instructions.slice(1)];
151
+ }
152
+ } else {
153
+ newInstructions = [
154
+ createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
155
+ ...transaction.instructions.slice(1)
156
+ ];
157
+ }
158
+ } else {
159
+ newInstructions = [
160
+ createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
161
+ ...transaction.instructions
162
+ ];
163
+ }
164
+ const out = {
165
+ ...getUnsignedTransaction(transaction),
166
+ instructions: newInstructions,
167
+ lifetimeConstraint: {
168
+ nonce
169
+ }
170
+ };
171
+ Object.freeze(out);
172
+ return out;
173
+ }
174
+
175
+ // src/fee-payer.ts
176
+ function setTransactionFeePayer(feePayer, transaction) {
177
+ if ("feePayer" in transaction && feePayer === transaction.feePayer) {
178
+ return transaction;
179
+ }
180
+ const out = {
181
+ ...getUnsignedTransaction(transaction),
182
+ feePayer
183
+ };
184
+ Object.freeze(out);
185
+ return out;
186
+ }
187
+
188
+ // src/instructions.ts
189
+ function appendTransactionInstruction(instruction, transaction) {
190
+ const out = {
191
+ ...getUnsignedTransaction(transaction),
192
+ instructions: [...transaction.instructions, instruction]
193
+ };
194
+ Object.freeze(out);
195
+ return out;
196
+ }
197
+ function prependTransactionInstruction(instruction, transaction) {
198
+ const out = {
199
+ ...getUnsignedTransaction(transaction),
200
+ instructions: [instruction, ...transaction.instructions]
201
+ };
202
+ Object.freeze(out);
203
+ return out;
204
+ }
103
205
  function upsert(addressMap, address, update) {
104
206
  addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
105
207
  }
@@ -152,7 +254,7 @@ function getAddressMapFromInstructions(feePayer, instructions) {
152
254
  const shouldReplaceEntry = (
153
255
  // Consider using the new LOOKUP_TABLE if its address is different...
154
256
  entry.lookupTableAddress !== accountMeta.lookupTableAddress && // ...and sorts before the existing one.
155
- (addressComparator || (addressComparator = keys.getBase58EncodedAddressComparator()))(
257
+ (addressComparator ||= addresses.getAddressComparator())(
156
258
  accountMeta.lookupTableAddress,
157
259
  entry.lookupTableAddress
158
260
  ) < 0
@@ -258,7 +360,7 @@ function getOrderedAccountsFromAddressMap(addressMap) {
258
360
  if (leftIsWritable !== isWritableRole(rightEntry.role)) {
259
361
  return leftIsWritable ? -1 : 1;
260
362
  }
261
- addressComparator || (addressComparator = keys.getBase58EncodedAddressComparator());
363
+ addressComparator ||= addresses.getAddressComparator();
262
364
  if (leftEntry[TYPE] === 1 /* LOOKUP_TABLE */ && rightEntry[TYPE] === 1 /* LOOKUP_TABLE */ && leftEntry.lookupTableAddress !== rightEntry.lookupTableAddress) {
263
365
  return addressComparator(leftEntry.lookupTableAddress, rightEntry.lookupTableAddress);
264
366
  } else {
@@ -271,23 +373,22 @@ function getOrderedAccountsFromAddressMap(addressMap) {
271
373
  return orderedAccounts;
272
374
  }
273
375
  function getCompiledAddressTableLookups(orderedAccounts) {
274
- var _a;
275
376
  const index = {};
276
377
  for (const account of orderedAccounts) {
277
378
  if (!("lookupTableAddress" in account)) {
278
379
  continue;
279
380
  }
280
- const entry = index[_a = account.lookupTableAddress] || (index[_a] = {
381
+ const entry = index[account.lookupTableAddress] ||= {
281
382
  readableIndices: [],
282
383
  writableIndices: []
283
- });
384
+ };
284
385
  if (account.role === AccountRole.WRITABLE) {
285
386
  entry.writableIndices.push(account.addressIndex);
286
387
  } else {
287
388
  entry.readableIndices.push(account.addressIndex);
288
389
  }
289
390
  }
290
- return Object.keys(index).sort(keys.getBase58EncodedAddressComparator()).map((lookupTableAddress) => ({
391
+ return Object.keys(index).sort(addresses.getAddressComparator()).map((lookupTableAddress) => ({
291
392
  lookupTableAddress,
292
393
  ...index[lookupTableAddress]
293
394
  }));
@@ -366,151 +467,189 @@ function compileMessage(transaction) {
366
467
  version: transaction.version
367
468
  };
368
469
  }
369
- function getAddressTableLookupCodec() {
370
- return umiSerializers.struct(
371
- [
470
+ var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
471
+ var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
472
+ var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
473
+ 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";
474
+ var memoizedAddressTableLookupEncoder;
475
+ function getAddressTableLookupEncoder() {
476
+ if (!memoizedAddressTableLookupEncoder) {
477
+ memoizedAddressTableLookupEncoder = codecsDataStructures.getStructEncoder(
372
478
  [
373
- "lookupTableAddress",
374
- keys.getBase58EncodedAddressCodec(
375
- __DEV__ ? {
376
- description: "The address of the address lookup table account from which instruction addresses should be looked up"
377
- } : void 0
378
- )
479
+ ["lookupTableAddress", addresses.getAddressEncoder({ description: lookupTableAddressDescription })],
480
+ [
481
+ "writableIndices",
482
+ codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), {
483
+ description: writableIndicesDescription,
484
+ size: codecsNumbers.getShortU16Encoder()
485
+ })
486
+ ],
487
+ [
488
+ "readableIndices",
489
+ codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), {
490
+ description: readableIndicesDescription,
491
+ size: codecsNumbers.getShortU16Encoder()
492
+ })
493
+ ]
379
494
  ],
495
+ { description: addressTableLookupDescription }
496
+ );
497
+ }
498
+ return memoizedAddressTableLookupEncoder;
499
+ }
500
+ var memoizedAddressTableLookupDecoder;
501
+ function getAddressTableLookupDecoder() {
502
+ if (!memoizedAddressTableLookupDecoder) {
503
+ memoizedAddressTableLookupDecoder = codecsDataStructures.getStructDecoder(
380
504
  [
381
- "writableIndices",
382
- umiSerializers.array(umiSerializers.u8(), {
383
- ...__DEV__ ? {
384
- description: "The indices of the accounts in the lookup table that should be loaded as writeable"
385
- } : null,
386
- size: umiSerializers.shortU16()
387
- })
505
+ ["lookupTableAddress", addresses.getAddressDecoder({ description: lookupTableAddressDescription })],
506
+ [
507
+ "writableIndices",
508
+ codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), {
509
+ description: writableIndicesDescription,
510
+ size: codecsNumbers.getShortU16Decoder()
511
+ })
512
+ ],
513
+ [
514
+ "readableIndices",
515
+ codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), {
516
+ description: readableIndicesDescription,
517
+ size: codecsNumbers.getShortU16Decoder()
518
+ })
519
+ ]
388
520
  ],
389
- [
390
- "readableIndices",
391
- umiSerializers.array(umiSerializers.u8(), {
392
- ...__DEV__ ? {
393
- description: "The indices of the accounts in the lookup table that should be loaded as read-only"
394
- } : void 0,
395
- size: umiSerializers.shortU16()
396
- })
397
- ]
398
- ],
399
- __DEV__ ? {
400
- description: "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"
401
- } : void 0
402
- );
521
+ { description: addressTableLookupDescription }
522
+ );
523
+ }
524
+ return memoizedAddressTableLookupDecoder;
525
+ }
526
+ var memoizedU8Encoder;
527
+ function getMemoizedU8Encoder() {
528
+ if (!memoizedU8Encoder)
529
+ memoizedU8Encoder = codecsNumbers.getU8Encoder();
530
+ return memoizedU8Encoder;
531
+ }
532
+ function getMemoizedU8EncoderDescription(description) {
533
+ const encoder = getMemoizedU8Encoder();
534
+ return {
535
+ ...encoder,
536
+ description: description ?? encoder.description
537
+ };
538
+ }
539
+ var memoizedU8Decoder;
540
+ function getMemoizedU8Decoder() {
541
+ if (!memoizedU8Decoder)
542
+ memoizedU8Decoder = codecsNumbers.getU8Decoder();
543
+ return memoizedU8Decoder;
544
+ }
545
+ function getMemoizedU8DecoderDescription(description) {
546
+ const decoder = getMemoizedU8Decoder();
547
+ return {
548
+ ...decoder,
549
+ description: description ?? decoder.description
550
+ };
403
551
  }
404
- function getMessageHeaderCodec() {
405
- return umiSerializers.struct(
552
+ 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;
553
+ 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;
554
+ var numReadonlyNonSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable" : void 0;
555
+ var messageHeaderDescription = __DEV__ ? "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses" : void 0;
556
+ function getMessageHeaderEncoder() {
557
+ return codecsDataStructures.getStructEncoder(
406
558
  [
407
- [
408
- "numSignerAccounts",
409
- umiSerializers.u8(
410
- __DEV__ ? {
411
- description: "The expected number of addresses in the static address list belonging to accounts that are required to sign this transaction"
412
- } : void 0
413
- )
414
- ],
415
- [
416
- "numReadonlySignerAccounts",
417
- umiSerializers.u8(
418
- __DEV__ ? {
419
- description: "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"
420
- } : void 0
421
- )
422
- ],
423
- [
424
- "numReadonlyNonSignerAccounts",
425
- umiSerializers.u8(
426
- __DEV__ ? {
427
- description: "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable"
428
- } : void 0
429
- )
430
- ]
559
+ ["numSignerAccounts", getMemoizedU8EncoderDescription(numSignerAccountsDescription)],
560
+ ["numReadonlySignerAccounts", getMemoizedU8EncoderDescription(numReadonlySignerAccountsDescription)],
561
+ ["numReadonlyNonSignerAccounts", getMemoizedU8EncoderDescription(numReadonlyNonSignerAccountsDescription)]
431
562
  ],
432
- __DEV__ ? {
433
- description: "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses"
434
- } : void 0
563
+ {
564
+ description: messageHeaderDescription
565
+ }
435
566
  );
436
567
  }
437
- function getInstructionCodec() {
438
- return umiSerializers.mapSerializer(
439
- umiSerializers.struct([
440
- [
441
- "programAddressIndex",
442
- umiSerializers.u8(
443
- __DEV__ ? {
444
- description: "The index of the program being called, according to the well-ordered accounts list for this transaction"
445
- } : void 0
446
- )
447
- ],
448
- [
449
- "addressIndices",
450
- umiSerializers.array(
451
- umiSerializers.u8({
452
- description: __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : ""
453
- }),
454
- {
455
- description: __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" : "",
456
- size: umiSerializers.shortU16()
457
- }
458
- )
459
- ],
460
- [
461
- "data",
462
- umiSerializers.bytes({
463
- description: __DEV__ ? "An optional buffer of data passed to the instruction" : "",
464
- size: umiSerializers.shortU16()
465
- })
466
- ]
467
- ]),
468
- (value) => {
469
- if (value.addressIndices !== void 0 && value.data !== void 0) {
470
- return value;
471
- }
472
- return {
473
- ...value,
474
- addressIndices: value.addressIndices ?? [],
475
- data: value.data ?? new Uint8Array(0)
476
- };
477
- },
478
- (value) => {
479
- if (value.addressIndices.length && value.data.byteLength) {
480
- return value;
481
- }
482
- const { addressIndices, data, ...rest } = value;
483
- return {
484
- ...rest,
485
- ...addressIndices.length ? { addressIndices } : null,
486
- ...data.byteLength ? { data } : null
487
- };
568
+ function getMessageHeaderDecoder() {
569
+ return codecsDataStructures.getStructDecoder(
570
+ [
571
+ ["numSignerAccounts", getMemoizedU8DecoderDescription(numSignerAccountsDescription)],
572
+ ["numReadonlySignerAccounts", getMemoizedU8DecoderDescription(numReadonlySignerAccountsDescription)],
573
+ ["numReadonlyNonSignerAccounts", getMemoizedU8DecoderDescription(numReadonlyNonSignerAccountsDescription)]
574
+ ],
575
+ {
576
+ description: messageHeaderDescription
488
577
  }
489
578
  );
490
579
  }
491
-
492
- // src/serializers/unimplemented.ts
493
- function getError(type, name) {
494
- const functionSuffix = name + type[0].toUpperCase() + type.slice(1);
495
- return new Error(
496
- `No ${type} exists for ${name}. Use \`get${functionSuffix}()\` if you need a ${type}, and \`get${name}Codec()\` if you need to both encode and decode ${name}`
497
- );
580
+ var programAddressIndexDescription = __DEV__ ? "The index of the program being called, according to the well-ordered accounts list for this transaction" : "programAddressIndex";
581
+ var accountIndexDescription = __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : void 0;
582
+ 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";
583
+ var dataDescription = __DEV__ ? "An optional buffer of data passed to the instruction" : "data";
584
+ var memoizedGetInstructionEncoder;
585
+ function getInstructionEncoder() {
586
+ if (!memoizedGetInstructionEncoder) {
587
+ memoizedGetInstructionEncoder = codecsCore.mapEncoder(
588
+ codecsDataStructures.getStructEncoder([
589
+ ["programAddressIndex", codecsNumbers.getU8Encoder({ description: programAddressIndexDescription })],
590
+ [
591
+ "accountIndices",
592
+ codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder({ description: accountIndexDescription }), {
593
+ description: accountIndicesDescription,
594
+ size: codecsNumbers.getShortU16Encoder()
595
+ })
596
+ ],
597
+ ["data", codecsDataStructures.getBytesEncoder({ description: dataDescription, size: codecsNumbers.getShortU16Encoder() })]
598
+ ]),
599
+ // Convert an instruction to have all fields defined
600
+ (instruction) => {
601
+ if (instruction.accountIndices !== void 0 && instruction.data !== void 0) {
602
+ return instruction;
603
+ }
604
+ return {
605
+ ...instruction,
606
+ accountIndices: instruction.accountIndices ?? [],
607
+ data: instruction.data ?? new Uint8Array(0)
608
+ };
609
+ }
610
+ );
611
+ }
612
+ return memoizedGetInstructionEncoder;
498
613
  }
499
- function getUnimplementedDecoder(name) {
500
- return () => {
501
- throw getError("decoder", name);
502
- };
614
+ var memoizedGetInstructionDecoder;
615
+ function getInstructionDecoder() {
616
+ if (!memoizedGetInstructionDecoder) {
617
+ memoizedGetInstructionDecoder = codecsCore.mapDecoder(
618
+ codecsDataStructures.getStructDecoder([
619
+ ["programAddressIndex", codecsNumbers.getU8Decoder({ description: programAddressIndexDescription })],
620
+ [
621
+ "accountIndices",
622
+ codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder({ description: accountIndexDescription }), {
623
+ description: accountIndicesDescription,
624
+ size: codecsNumbers.getShortU16Decoder()
625
+ })
626
+ ],
627
+ ["data", codecsDataStructures.getBytesDecoder({ description: dataDescription, size: codecsNumbers.getShortU16Decoder() })]
628
+ ]),
629
+ // Convert an instruction to exclude optional fields if they are empty
630
+ (instruction) => {
631
+ if (instruction.accountIndices.length && instruction.data.byteLength) {
632
+ return instruction;
633
+ }
634
+ const { accountIndices, data, ...rest } = instruction;
635
+ return {
636
+ ...rest,
637
+ ...accountIndices.length ? { accountIndices } : null,
638
+ ...data.byteLength ? { data } : null
639
+ };
640
+ }
641
+ );
642
+ }
643
+ return memoizedGetInstructionDecoder;
503
644
  }
504
-
505
- // src/serializers/transaction-version.ts
506
645
  var VERSION_FLAG_MASK = 128;
507
646
  var BASE_CONFIG = {
508
647
  description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
509
648
  fixedSize: null,
510
649
  maxSize: 1
511
650
  };
512
- function deserialize(bytes3, offset = 0) {
513
- const firstByte = bytes3[offset];
651
+ function decode(bytes, offset = 0) {
652
+ const firstByte = bytes[offset];
514
653
  if ((firstByte & VERSION_FLAG_MASK) === 0) {
515
654
  return ["legacy", offset];
516
655
  } else {
@@ -518,7 +657,7 @@ function deserialize(bytes3, offset = 0) {
518
657
  return [version, offset + 1];
519
658
  }
520
659
  }
521
- function serialize(value) {
660
+ function encode(value) {
522
661
  if (value === "legacy") {
523
662
  return new Uint8Array();
524
663
  }
@@ -527,105 +666,143 @@ function serialize(value) {
527
666
  }
528
667
  return new Uint8Array([value | VERSION_FLAG_MASK]);
529
668
  }
530
- function getTransactionVersionCodec() {
669
+ function getTransactionVersionDecoder() {
531
670
  return {
532
671
  ...BASE_CONFIG,
533
- deserialize,
534
- serialize
672
+ decode
673
+ };
674
+ }
675
+ function getTransactionVersionEncoder() {
676
+ return {
677
+ ...BASE_CONFIG,
678
+ encode
535
679
  };
536
680
  }
537
681
 
538
682
  // src/serializers/message.ts
539
- var BASE_CONFIG2 = {
540
- description: __DEV__ ? "The wire format of a Solana transaction message" : "",
541
- fixedSize: null,
542
- maxSize: null
543
- };
544
- function serialize2(compiledMessage) {
545
- if (compiledMessage.version === "legacy") {
546
- return umiSerializers.struct(getPreludeStructSerializerTuple()).serialize(compiledMessage);
547
- } else {
548
- return umiSerializers.mapSerializer(
549
- umiSerializers.struct([
550
- ...getPreludeStructSerializerTuple(),
551
- ["addressTableLookups", getAddressTableLookupsSerializer()]
552
- ]),
553
- (value) => {
554
- if (value.version === "legacy") {
555
- return value;
556
- }
557
- return {
558
- ...value,
559
- addressTableLookups: value.addressTableLookups ?? []
560
- };
683
+ var staticAccountsDescription = __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "staticAccounts";
684
+ var lifetimeTokenDescription = __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "lifetimeToken";
685
+ var instructionsDescription = __DEV__ ? "A compact-array of instructions belonging to this transaction" : "instructions";
686
+ var addressTableLookupsDescription = __DEV__ ? "A compact array of address table lookups belonging to this transaction" : "addressTableLookups";
687
+ function getCompiledMessageLegacyEncoder() {
688
+ return codecsDataStructures.getStructEncoder(getPreludeStructEncoderTuple());
689
+ }
690
+ function getCompiledMessageVersionedEncoder() {
691
+ return codecsCore.mapEncoder(
692
+ codecsDataStructures.getStructEncoder([
693
+ ...getPreludeStructEncoderTuple(),
694
+ ["addressTableLookups", getAddressTableLookupArrayEncoder()]
695
+ ]),
696
+ (value) => {
697
+ if (value.version === "legacy") {
698
+ return value;
561
699
  }
562
- ).serialize(compiledMessage);
563
- }
700
+ return {
701
+ ...value,
702
+ addressTableLookups: value.addressTableLookups ?? []
703
+ };
704
+ }
705
+ );
564
706
  }
565
- function getPreludeStructSerializerTuple() {
707
+ function getPreludeStructEncoderTuple() {
566
708
  return [
567
- ["version", getTransactionVersionCodec()],
568
- ["header", getMessageHeaderCodec()],
709
+ ["version", getTransactionVersionEncoder()],
710
+ ["header", getMessageHeaderEncoder()],
569
711
  [
570
712
  "staticAccounts",
571
- umiSerializers.array(keys.getBase58EncodedAddressCodec(), {
572
- description: __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "",
573
- size: umiSerializers.shortU16()
713
+ codecsDataStructures.getArrayEncoder(addresses.getAddressEncoder(), {
714
+ description: staticAccountsDescription,
715
+ size: codecsNumbers.getShortU16Encoder()
574
716
  })
575
717
  ],
576
718
  [
577
719
  "lifetimeToken",
578
- umiSerializers.string({
579
- description: __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "",
580
- encoding: umiSerializers.base58,
720
+ codecsStrings.getStringEncoder({
721
+ description: lifetimeTokenDescription,
722
+ encoding: codecsStrings.getBase58Encoder(),
581
723
  size: 32
582
724
  })
583
725
  ],
584
726
  [
585
727
  "instructions",
586
- umiSerializers.array(getInstructionCodec(), {
587
- description: __DEV__ ? "A compact-array of instructions belonging to this transaction" : "",
588
- size: umiSerializers.shortU16()
728
+ codecsDataStructures.getArrayEncoder(getInstructionEncoder(), {
729
+ description: instructionsDescription,
730
+ size: codecsNumbers.getShortU16Encoder()
589
731
  })
590
732
  ]
591
733
  ];
592
734
  }
593
- function getAddressTableLookupsSerializer() {
594
- return umiSerializers.array(getAddressTableLookupCodec(), {
595
- ...__DEV__ ? { description: "A compact array of address table lookups belonging to this transaction" } : null,
596
- size: umiSerializers.shortU16()
735
+ function getPreludeStructDecoderTuple() {
736
+ return [
737
+ ["version", getTransactionVersionDecoder()],
738
+ ["header", getMessageHeaderDecoder()],
739
+ [
740
+ "staticAccounts",
741
+ codecsDataStructures.getArrayDecoder(addresses.getAddressDecoder(), {
742
+ description: staticAccountsDescription,
743
+ size: codecsNumbers.getShortU16Decoder()
744
+ })
745
+ ],
746
+ [
747
+ "lifetimeToken",
748
+ codecsStrings.getStringDecoder({
749
+ description: lifetimeTokenDescription,
750
+ encoding: codecsStrings.getBase58Decoder(),
751
+ size: 32
752
+ })
753
+ ],
754
+ [
755
+ "instructions",
756
+ codecsDataStructures.getArrayDecoder(getInstructionDecoder(), {
757
+ description: instructionsDescription,
758
+ size: codecsNumbers.getShortU16Decoder()
759
+ })
760
+ ],
761
+ ["addressTableLookups", getAddressTableLookupArrayDecoder()]
762
+ ];
763
+ }
764
+ function getAddressTableLookupArrayEncoder() {
765
+ return codecsDataStructures.getArrayEncoder(getAddressTableLookupEncoder(), {
766
+ description: addressTableLookupsDescription,
767
+ size: codecsNumbers.getShortU16Encoder()
597
768
  });
598
769
  }
770
+ function getAddressTableLookupArrayDecoder() {
771
+ return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), {
772
+ description: addressTableLookupsDescription,
773
+ size: codecsNumbers.getShortU16Decoder()
774
+ });
775
+ }
776
+ var messageDescription = __DEV__ ? "The wire format of a Solana transaction message" : "message";
599
777
  function getCompiledMessageEncoder() {
600
778
  return {
601
- ...BASE_CONFIG2,
602
- deserialize: getUnimplementedDecoder("CompiledMessage"),
603
- serialize: serialize2
779
+ description: messageDescription,
780
+ encode: (compiledMessage) => {
781
+ if (compiledMessage.version === "legacy") {
782
+ return getCompiledMessageLegacyEncoder().encode(compiledMessage);
783
+ } else {
784
+ return getCompiledMessageVersionedEncoder().encode(compiledMessage);
785
+ }
786
+ },
787
+ fixedSize: null,
788
+ maxSize: null
604
789
  };
605
790
  }
606
-
607
- // src/signatures.ts
608
- async function getCompiledMessageSignature(message, secretKey) {
609
- const wireMessageBytes = getCompiledMessageEncoder().serialize(message);
610
- const signature = await keys.signBytes(secretKey, wireMessageBytes);
611
- return signature;
791
+ function getCompiledMessageDecoder() {
792
+ return codecsCore.mapDecoder(
793
+ codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple(), {
794
+ description: messageDescription
795
+ }),
796
+ ({ addressTableLookups, ...restOfMessage }) => {
797
+ if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
798
+ return restOfMessage;
799
+ }
800
+ return { ...restOfMessage, addressTableLookups };
801
+ }
802
+ );
612
803
  }
613
- async function signTransaction(keyPair, transaction) {
614
- const compiledMessage = compileMessage(transaction);
615
- const [signerPublicKey, signature] = await Promise.all([
616
- keys.getBase58EncodedAddressFromPublicKey(keyPair.publicKey),
617
- getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
618
- ]);
619
- const nextSignatures = {
620
- ..."signatures" in transaction ? transaction.signatures : null,
621
- ...{ [signerPublicKey]: signature }
622
- };
623
- const out = {
624
- ...transaction,
625
- signatures: nextSignatures
626
- };
627
- Object.freeze(out);
628
- return out;
804
+ function getCompiledMessageCodec() {
805
+ return codecsCore.combineCodec(getCompiledMessageEncoder(), getCompiledMessageDecoder());
629
806
  }
630
807
 
631
808
  // src/compile-transaction.ts
@@ -645,47 +822,239 @@ function getCompiledTransaction(transaction) {
645
822
  signatures
646
823
  };
647
824
  }
825
+ function getAccountMetas(message) {
826
+ const { header } = message;
827
+ const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
828
+ const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
829
+ const accountMetas = [];
830
+ let accountIndex = 0;
831
+ for (let i = 0; i < numWritableSignerAccounts; i++) {
832
+ accountMetas.push({
833
+ address: message.staticAccounts[accountIndex],
834
+ role: AccountRole.WRITABLE_SIGNER
835
+ });
836
+ accountIndex++;
837
+ }
838
+ for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
839
+ accountMetas.push({
840
+ address: message.staticAccounts[accountIndex],
841
+ role: AccountRole.READONLY_SIGNER
842
+ });
843
+ accountIndex++;
844
+ }
845
+ for (let i = 0; i < numWritableNonSignerAccounts; i++) {
846
+ accountMetas.push({
847
+ address: message.staticAccounts[accountIndex],
848
+ role: AccountRole.WRITABLE
849
+ });
850
+ accountIndex++;
851
+ }
852
+ for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
853
+ accountMetas.push({
854
+ address: message.staticAccounts[accountIndex],
855
+ role: AccountRole.READONLY
856
+ });
857
+ accountIndex++;
858
+ }
859
+ return accountMetas;
860
+ }
861
+ function convertInstruction(instruction, accountMetas) {
862
+ const programAddress = accountMetas[instruction.programAddressIndex]?.address;
863
+ if (!programAddress) {
864
+ throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
865
+ }
866
+ const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
867
+ const { data } = instruction;
868
+ return {
869
+ programAddress,
870
+ ...accounts && accounts.length ? { accounts } : {},
871
+ ...data && data.length ? { data } : {}
872
+ };
873
+ }
874
+ function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
875
+ if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
876
+ return {
877
+ blockhash: messageLifetimeToken,
878
+ lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
879
+ // U64 MAX
880
+ };
881
+ } else {
882
+ const nonceAccountAddress = firstInstruction.accounts[0].address;
883
+ addresses.assertIsAddress(nonceAccountAddress);
884
+ const nonceAuthorityAddress = firstInstruction.accounts[2].address;
885
+ addresses.assertIsAddress(nonceAuthorityAddress);
886
+ return {
887
+ nonce: messageLifetimeToken,
888
+ nonceAccountAddress,
889
+ nonceAuthorityAddress
890
+ };
891
+ }
892
+ }
893
+ function convertSignatures(compiledTransaction) {
894
+ const {
895
+ compiledMessage: { staticAccounts },
896
+ signatures
897
+ } = compiledTransaction;
898
+ return signatures.reduce((acc, sig, index) => {
899
+ const allZeros = sig.every((byte) => byte === 0);
900
+ if (allZeros)
901
+ return acc;
902
+ const address = staticAccounts[index];
903
+ return { ...acc, [address]: sig };
904
+ }, {});
905
+ }
906
+ function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
907
+ const { compiledMessage } = compiledTransaction;
908
+ if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
909
+ throw new Error("Cannot convert transaction with addressTableLookups");
910
+ }
911
+ const feePayer = compiledMessage.staticAccounts[0];
912
+ if (!feePayer)
913
+ throw new Error("No fee payer set in CompiledTransaction");
914
+ const accountMetas = getAccountMetas(compiledMessage);
915
+ const instructions = compiledMessage.instructions.map(
916
+ (compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
917
+ );
918
+ const firstInstruction = instructions[0];
919
+ const lifetimeConstraint = getLifetimeConstraint(
920
+ compiledMessage.lifetimeToken,
921
+ firstInstruction,
922
+ lastValidBlockHeight
923
+ );
924
+ const signatures = convertSignatures(compiledTransaction);
925
+ return functional.pipe(
926
+ createTransaction({ version: compiledMessage.version }),
927
+ (tx) => setTransactionFeePayer(feePayer, tx),
928
+ (tx) => instructions.reduce((acc, instruction) => {
929
+ return appendTransactionInstruction(instruction, acc);
930
+ }, tx),
931
+ (tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
932
+ (tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
933
+ );
934
+ }
648
935
 
649
936
  // src/serializers/transaction.ts
650
- var BASE_CONFIG3 = {
651
- description: __DEV__ ? "The wire format of a Solana transaction" : "",
652
- fixedSize: null,
653
- maxSize: null
654
- };
655
- function serialize3(transaction) {
656
- const compiledTransaction = getCompiledTransaction(transaction);
657
- return umiSerializers.struct([
937
+ var signaturesDescription = __DEV__ ? "A compact array of 64-byte, base-64 encoded Ed25519 signatures" : "signatures";
938
+ var transactionDescription = __DEV__ ? "The wire format of a Solana transaction" : "transaction";
939
+ function getCompiledTransactionEncoder() {
940
+ return codecsDataStructures.getStructEncoder(
658
941
  [
659
- "signatures",
660
- umiSerializers.array(umiSerializers.bytes({ size: 64 }), {
661
- ...__DEV__ ? { description: "A compact array of 64-byte, base-64 encoded Ed25519 signatures" } : null,
662
- size: umiSerializers.shortU16()
663
- })
942
+ [
943
+ "signatures",
944
+ codecsDataStructures.getArrayEncoder(codecsDataStructures.getBytesEncoder({ size: 64 }), {
945
+ description: signaturesDescription,
946
+ size: codecsNumbers.getShortU16Encoder()
947
+ })
948
+ ],
949
+ ["compiledMessage", getCompiledMessageEncoder()]
950
+ ],
951
+ {
952
+ description: transactionDescription
953
+ }
954
+ );
955
+ }
956
+ function getSignatureDecoder() {
957
+ return codecsCore.mapDecoder(codecsDataStructures.getBytesDecoder({ size: 64 }), (bytes) => bytes);
958
+ }
959
+ function getCompiledTransactionDecoder() {
960
+ return codecsDataStructures.getStructDecoder(
961
+ [
962
+ [
963
+ "signatures",
964
+ codecsDataStructures.getArrayDecoder(getSignatureDecoder(), {
965
+ description: signaturesDescription,
966
+ size: codecsNumbers.getShortU16Decoder()
967
+ })
968
+ ],
969
+ ["compiledMessage", getCompiledMessageDecoder()]
664
970
  ],
665
- ["compiledMessage", getCompiledMessageEncoder()]
666
- ]).serialize(compiledTransaction);
971
+ {
972
+ description: transactionDescription
973
+ }
974
+ );
667
975
  }
668
976
  function getTransactionEncoder() {
669
- return {
670
- ...BASE_CONFIG3,
671
- deserialize: getUnimplementedDecoder("CompiledMessage"),
672
- serialize: serialize3
977
+ return codecsCore.mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
978
+ }
979
+ function getTransactionDecoder(lastValidBlockHeight) {
980
+ return codecsCore.mapDecoder(
981
+ getCompiledTransactionDecoder(),
982
+ (compiledTransaction) => decompileTransaction(compiledTransaction, lastValidBlockHeight)
983
+ );
984
+ }
985
+ function getTransactionCodec(lastValidBlockHeight) {
986
+ return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
987
+ }
988
+ var base58Decoder;
989
+ function getSignatureFromTransaction(transaction) {
990
+ if (!base58Decoder)
991
+ base58Decoder = codecsStrings.getBase58Decoder();
992
+ const signatureBytes = transaction.signatures[transaction.feePayer];
993
+ if (!signatureBytes) {
994
+ throw new Error(
995
+ "Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
996
+ );
997
+ }
998
+ const transactionSignature = base58Decoder.decode(signatureBytes)[0];
999
+ return transactionSignature;
1000
+ }
1001
+ async function partiallySignTransaction(keyPairs, transaction) {
1002
+ const compiledMessage = compileMessage(transaction);
1003
+ const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
1004
+ const wireMessageBytes = getCompiledMessageEncoder().encode(compiledMessage);
1005
+ const publicKeySignaturePairs = await Promise.all(
1006
+ keyPairs.map(
1007
+ (keyPair) => Promise.all([addresses.getAddressFromPublicKey(keyPair.publicKey), keys.signBytes(keyPair.privateKey, wireMessageBytes)])
1008
+ )
1009
+ );
1010
+ for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
1011
+ nextSignatures[signerPublicKey] = signature;
1012
+ }
1013
+ const out = {
1014
+ ...transaction,
1015
+ signatures: nextSignatures
673
1016
  };
1017
+ Object.freeze(out);
1018
+ return out;
1019
+ }
1020
+ async function signTransaction(keyPairs, transaction) {
1021
+ const out = await partiallySignTransaction(keyPairs, transaction);
1022
+ assertTransactionIsFullySigned(out);
1023
+ Object.freeze(out);
1024
+ return out;
1025
+ }
1026
+ function assertTransactionIsFullySigned(transaction) {
1027
+ const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
1028
+ const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
1029
+ requiredSigners.forEach((address) => {
1030
+ if (!transaction.signatures[address]) {
1031
+ throw new Error(`Transaction is missing signature for address \`${address}\``);
1032
+ }
1033
+ });
674
1034
  }
675
-
676
- // src/wire-transaction.ts
677
1035
  function getBase64EncodedWireTransaction(transaction) {
678
- const wireTransactionBytes = getTransactionEncoder().serialize(transaction);
679
- {
680
- return btoa(String.fromCharCode(...wireTransactionBytes));
681
- }
1036
+ const wireTransactionBytes = getTransactionEncoder().encode(transaction);
1037
+ return codecsStrings.getBase64Decoder().decode(wireTransactionBytes)[0];
682
1038
  }
683
1039
 
684
1040
  exports.appendTransactionInstruction = appendTransactionInstruction;
1041
+ exports.assertIsBlockhash = assertIsBlockhash;
1042
+ exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
1043
+ exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
1044
+ exports.compileMessage = compileMessage;
685
1045
  exports.createTransaction = createTransaction;
686
1046
  exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
1047
+ exports.getCompiledMessageCodec = getCompiledMessageCodec;
1048
+ exports.getCompiledMessageDecoder = getCompiledMessageDecoder;
1049
+ exports.getCompiledMessageEncoder = getCompiledMessageEncoder;
1050
+ exports.getSignatureFromTransaction = getSignatureFromTransaction;
1051
+ exports.getTransactionCodec = getTransactionCodec;
1052
+ exports.getTransactionDecoder = getTransactionDecoder;
1053
+ exports.getTransactionEncoder = getTransactionEncoder;
1054
+ exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
1055
+ exports.partiallySignTransaction = partiallySignTransaction;
687
1056
  exports.prependTransactionInstruction = prependTransactionInstruction;
688
1057
  exports.setTransactionFeePayer = setTransactionFeePayer;
1058
+ exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
1059
+ exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
689
1060
  exports.signTransaction = signTransaction;
690
- //# sourceMappingURL=out.js.map
691
- //# sourceMappingURL=index.browser.cjs.map