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