@solana/transactions 2.0.0-experimental.7da1908 → 2.0.0-experimental.7ed772d
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 +420 -322
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +411 -319
- package/dist/index.browser.js.map +1 -1
- package/dist/index.development.js +1004 -759
- package/dist/index.development.js.map +1 -1
- package/dist/index.native.js +411 -319
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +422 -320
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +413 -319
- package/dist/index.node.js.map +1 -1
- package/dist/index.production.min.js +23 -15
- package/dist/types/accounts.d.ts +2 -2
- package/dist/types/accounts.d.ts.map +1 -1
- package/dist/types/blockhash.d.ts +1 -0
- package/dist/types/blockhash.d.ts.map +1 -1
- 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 -1
- package/dist/types/compile-static-accounts.d.ts +2 -2
- package/dist/types/compile-static-accounts.d.ts.map +1 -1
- package/dist/types/compile-transaction.d.ts +5 -6
- package/dist/types/compile-transaction.d.ts.map +1 -1
- 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 +6 -6
- package/dist/types/durable-nonce.d.ts.map +1 -1
- package/dist/types/fee-payer.d.ts +4 -4
- package/dist/types/fee-payer.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/message.d.ts +1 -5
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/serializers/address-table-lookup.d.ts +5 -3
- package/dist/types/serializers/address-table-lookup.d.ts.map +1 -1
- package/dist/types/serializers/header.d.ts +4 -2
- package/dist/types/serializers/header.d.ts.map +1 -1
- 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 -1
- package/dist/types/serializers/message.d.ts +4 -4
- package/dist/types/serializers/message.d.ts.map +1 -1
- package/dist/types/serializers/transaction-version.d.ts +4 -4
- package/dist/types/serializers/transaction-version.d.ts.map +1 -1
- package/dist/types/serializers/transaction.d.ts +6 -5
- package/dist/types/serializers/transaction.d.ts.map +1 -1
- package/dist/types/signatures.d.ts +8 -12
- package/dist/types/signatures.d.ts.map +1 -1
- package/dist/types/types.d.ts +6 -13
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/wire-transaction.d.ts +1 -1
- package/dist/types/wire-transaction.d.ts.map +1 -1
- package/package.json +18 -14
- package/dist/types/serializers/unimplemented.d.ts +0 -3
- package/dist/types/serializers/unimplemented.d.ts.map +0 -1
package/dist/index.browser.cjs
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var codecsStrings = require('@solana/codecs-strings');
|
|
4
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');
|
|
5
9
|
var keys = require('@solana/keys');
|
|
6
10
|
|
|
7
|
-
//
|
|
8
|
-
var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
|
|
11
|
+
// src/blockhash.ts
|
|
9
12
|
|
|
10
13
|
// src/unsigned-transaction.ts
|
|
11
14
|
function getUnsignedTransaction(transaction) {
|
|
@@ -22,7 +25,10 @@ function getUnsignedTransaction(transaction) {
|
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
// src/blockhash.ts
|
|
28
|
+
var base58Encoder;
|
|
25
29
|
function assertIsBlockhash(putativeBlockhash) {
|
|
30
|
+
if (!base58Encoder)
|
|
31
|
+
base58Encoder = codecsStrings.getBase58Encoder();
|
|
26
32
|
try {
|
|
27
33
|
if (
|
|
28
34
|
// Lowest value (32 bytes of zeroes)
|
|
@@ -31,8 +37,8 @@ function assertIsBlockhash(putativeBlockhash) {
|
|
|
31
37
|
) {
|
|
32
38
|
throw new Error("Expected input string to decode to a byte array of length 32.");
|
|
33
39
|
}
|
|
34
|
-
const
|
|
35
|
-
const numBytes =
|
|
40
|
+
const bytes = base58Encoder.encode(putativeBlockhash);
|
|
41
|
+
const numBytes = bytes.byteLength;
|
|
36
42
|
if (numBytes !== 32) {
|
|
37
43
|
throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
|
|
38
44
|
}
|
|
@@ -42,6 +48,22 @@ function assertIsBlockhash(putativeBlockhash) {
|
|
|
42
48
|
});
|
|
43
49
|
}
|
|
44
50
|
}
|
|
51
|
+
function isTransactionWithBlockhashLifetime(transaction) {
|
|
52
|
+
const lifetimeConstraintShapeMatches = "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.blockhash === "string" && typeof transaction.lifetimeConstraint.lastValidBlockHeight === "bigint";
|
|
53
|
+
if (!lifetimeConstraintShapeMatches)
|
|
54
|
+
return false;
|
|
55
|
+
try {
|
|
56
|
+
assertIsBlockhash(transaction.lifetimeConstraint.blockhash);
|
|
57
|
+
return true;
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function assertIsTransactionWithBlockhashLifetime(transaction) {
|
|
63
|
+
if (!isTransactionWithBlockhashLifetime(transaction)) {
|
|
64
|
+
throw new Error("Transaction does not have a blockhash lifetime");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
45
67
|
function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
|
|
46
68
|
if ("lifetimeConstraint" in transaction && transaction.lifetimeConstraint.blockhash === blockhashLifetimeConstraint.blockhash && transaction.lifetimeConstraint.lastValidBlockHeight === blockhashLifetimeConstraint.lastValidBlockHeight) {
|
|
47
69
|
return transaction;
|
|
@@ -117,7 +139,7 @@ function isAdvanceNonceAccountInstruction(instruction) {
|
|
|
117
139
|
instruction.accounts?.length === 3 && // First account is nonce account address
|
|
118
140
|
instruction.accounts[0].address != null && instruction.accounts[0].role === AccountRole.WRITABLE && // Second account is recent blockhashes sysvar
|
|
119
141
|
instruction.accounts[1].address === RECENT_BLOCKHASHES_SYSVAR_ADDRESS && instruction.accounts[1].role === AccountRole.READONLY && // Third account is nonce authority account
|
|
120
|
-
instruction.accounts[2].address != null && instruction.accounts[2].role
|
|
142
|
+
instruction.accounts[2].address != null && isSignerRole(instruction.accounts[2].role);
|
|
121
143
|
}
|
|
122
144
|
function isAdvanceNonceAccountInstructionData(data) {
|
|
123
145
|
return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;
|
|
@@ -125,21 +147,38 @@ function isAdvanceNonceAccountInstructionData(data) {
|
|
|
125
147
|
function isDurableNonceTransaction(transaction) {
|
|
126
148
|
return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
|
|
127
149
|
}
|
|
150
|
+
function isAdvanceNonceAccountInstructionForNonce(instruction, nonceAccountAddress, nonceAuthorityAddress) {
|
|
151
|
+
return instruction.accounts[0].address === nonceAccountAddress && instruction.accounts[2].address === nonceAuthorityAddress;
|
|
152
|
+
}
|
|
128
153
|
function setTransactionLifetimeUsingDurableNonce({
|
|
129
154
|
nonce,
|
|
130
155
|
nonceAccountAddress,
|
|
131
156
|
nonceAuthorityAddress
|
|
132
157
|
}, transaction) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
158
|
+
let newInstructions;
|
|
159
|
+
const firstInstruction = transaction.instructions[0];
|
|
160
|
+
if (firstInstruction && isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
161
|
+
if (isAdvanceNonceAccountInstructionForNonce(firstInstruction, nonceAccountAddress, nonceAuthorityAddress)) {
|
|
162
|
+
if (isDurableNonceTransaction(transaction) && transaction.lifetimeConstraint.nonce === nonce) {
|
|
163
|
+
return transaction;
|
|
164
|
+
} else {
|
|
165
|
+
newInstructions = [firstInstruction, ...transaction.instructions.slice(1)];
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
newInstructions = [
|
|
169
|
+
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
170
|
+
...transaction.instructions.slice(1)
|
|
171
|
+
];
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
newInstructions = [
|
|
175
|
+
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
176
|
+
...transaction.instructions
|
|
177
|
+
];
|
|
136
178
|
}
|
|
137
179
|
const out = {
|
|
138
180
|
...getUnsignedTransaction(transaction),
|
|
139
|
-
instructions:
|
|
140
|
-
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
141
|
-
...isAlreadyDurableNonceTransaction ? transaction.instructions.slice(1) : transaction.instructions
|
|
142
|
-
],
|
|
181
|
+
instructions: newInstructions,
|
|
143
182
|
lifetimeConstraint: {
|
|
144
183
|
nonce
|
|
145
184
|
}
|
|
@@ -230,7 +269,7 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
230
269
|
const shouldReplaceEntry = (
|
|
231
270
|
// Consider using the new LOOKUP_TABLE if its address is different...
|
|
232
271
|
entry.lookupTableAddress !== accountMeta.lookupTableAddress && // ...and sorts before the existing one.
|
|
233
|
-
(addressComparator
|
|
272
|
+
(addressComparator ||= addresses.getAddressComparator())(
|
|
234
273
|
accountMeta.lookupTableAddress,
|
|
235
274
|
entry.lookupTableAddress
|
|
236
275
|
) < 0
|
|
@@ -336,7 +375,7 @@ function getOrderedAccountsFromAddressMap(addressMap) {
|
|
|
336
375
|
if (leftIsWritable !== isWritableRole(rightEntry.role)) {
|
|
337
376
|
return leftIsWritable ? -1 : 1;
|
|
338
377
|
}
|
|
339
|
-
addressComparator
|
|
378
|
+
addressComparator ||= addresses.getAddressComparator();
|
|
340
379
|
if (leftEntry[TYPE] === 1 /* LOOKUP_TABLE */ && rightEntry[TYPE] === 1 /* LOOKUP_TABLE */ && leftEntry.lookupTableAddress !== rightEntry.lookupTableAddress) {
|
|
341
380
|
return addressComparator(leftEntry.lookupTableAddress, rightEntry.lookupTableAddress);
|
|
342
381
|
} else {
|
|
@@ -349,23 +388,22 @@ function getOrderedAccountsFromAddressMap(addressMap) {
|
|
|
349
388
|
return orderedAccounts;
|
|
350
389
|
}
|
|
351
390
|
function getCompiledAddressTableLookups(orderedAccounts) {
|
|
352
|
-
var _a;
|
|
353
391
|
const index = {};
|
|
354
392
|
for (const account of orderedAccounts) {
|
|
355
393
|
if (!("lookupTableAddress" in account)) {
|
|
356
394
|
continue;
|
|
357
395
|
}
|
|
358
|
-
const entry = index[
|
|
396
|
+
const entry = index[account.lookupTableAddress] ||= {
|
|
359
397
|
readableIndices: [],
|
|
360
398
|
writableIndices: []
|
|
361
|
-
}
|
|
399
|
+
};
|
|
362
400
|
if (account.role === AccountRole.WRITABLE) {
|
|
363
401
|
entry.writableIndices.push(account.addressIndex);
|
|
364
402
|
} else {
|
|
365
403
|
entry.readableIndices.push(account.addressIndex);
|
|
366
404
|
}
|
|
367
405
|
}
|
|
368
|
-
return Object.keys(index).sort(addresses.
|
|
406
|
+
return Object.keys(index).sort(addresses.getAddressComparator()).map((lookupTableAddress) => ({
|
|
369
407
|
lookupTableAddress,
|
|
370
408
|
...index[lookupTableAddress]
|
|
371
409
|
}));
|
|
@@ -444,303 +482,395 @@ function compileMessage(transaction) {
|
|
|
444
482
|
version: transaction.version
|
|
445
483
|
};
|
|
446
484
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
addresses.getBase58EncodedAddressCodec(
|
|
453
|
-
__DEV__ ? {
|
|
454
|
-
description: "The address of the address lookup table account from which instruction addresses should be looked up"
|
|
455
|
-
} : void 0
|
|
456
|
-
)
|
|
457
|
-
],
|
|
485
|
+
var memoizedAddressTableLookupEncoder;
|
|
486
|
+
function getAddressTableLookupEncoder() {
|
|
487
|
+
if (!memoizedAddressTableLookupEncoder) {
|
|
488
|
+
memoizedAddressTableLookupEncoder = codecsDataStructures.getStructEncoder([
|
|
489
|
+
["lookupTableAddress", addresses.getAddressEncoder()],
|
|
458
490
|
[
|
|
459
491
|
"writableIndices",
|
|
460
|
-
|
|
461
|
-
...__DEV__ ? {
|
|
462
|
-
description: "The indices of the accounts in the lookup table that should be loaded as writeable"
|
|
463
|
-
} : null,
|
|
464
|
-
size: umiSerializers.shortU16()
|
|
465
|
-
})
|
|
492
|
+
codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), { size: codecsNumbers.getShortU16Encoder() })
|
|
466
493
|
],
|
|
467
494
|
[
|
|
468
495
|
"readableIndices",
|
|
469
|
-
|
|
470
|
-
...__DEV__ ? {
|
|
471
|
-
description: "The indices of the accounts in the lookup table that should be loaded as read-only"
|
|
472
|
-
} : void 0,
|
|
473
|
-
size: umiSerializers.shortU16()
|
|
474
|
-
})
|
|
496
|
+
codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), { size: codecsNumbers.getShortU16Encoder() })
|
|
475
497
|
]
|
|
476
|
-
]
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
498
|
+
]);
|
|
499
|
+
}
|
|
500
|
+
return memoizedAddressTableLookupEncoder;
|
|
501
|
+
}
|
|
502
|
+
var memoizedAddressTableLookupDecoder;
|
|
503
|
+
function getAddressTableLookupDecoder() {
|
|
504
|
+
if (!memoizedAddressTableLookupDecoder) {
|
|
505
|
+
memoizedAddressTableLookupDecoder = codecsDataStructures.getStructDecoder([
|
|
506
|
+
["lookupTableAddress", addresses.getAddressDecoder()],
|
|
507
|
+
["writableIndices", codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), { size: codecsNumbers.getShortU16Decoder() })],
|
|
508
|
+
["readableIndices", codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), { size: codecsNumbers.getShortU16Decoder() })]
|
|
509
|
+
]);
|
|
510
|
+
}
|
|
511
|
+
return memoizedAddressTableLookupDecoder;
|
|
512
|
+
}
|
|
513
|
+
var memoizedU8Encoder;
|
|
514
|
+
function getMemoizedU8Encoder() {
|
|
515
|
+
if (!memoizedU8Encoder)
|
|
516
|
+
memoizedU8Encoder = codecsNumbers.getU8Encoder();
|
|
517
|
+
return memoizedU8Encoder;
|
|
518
|
+
}
|
|
519
|
+
var memoizedU8Decoder;
|
|
520
|
+
function getMemoizedU8Decoder() {
|
|
521
|
+
if (!memoizedU8Decoder)
|
|
522
|
+
memoizedU8Decoder = codecsNumbers.getU8Decoder();
|
|
523
|
+
return memoizedU8Decoder;
|
|
524
|
+
}
|
|
525
|
+
function getMessageHeaderEncoder() {
|
|
526
|
+
return codecsDataStructures.getStructEncoder([
|
|
527
|
+
["numSignerAccounts", getMemoizedU8Encoder()],
|
|
528
|
+
["numReadonlySignerAccounts", getMemoizedU8Encoder()],
|
|
529
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8Encoder()]
|
|
530
|
+
]);
|
|
531
|
+
}
|
|
532
|
+
function getMessageHeaderDecoder() {
|
|
533
|
+
return codecsDataStructures.getStructDecoder([
|
|
534
|
+
["numSignerAccounts", getMemoizedU8Decoder()],
|
|
535
|
+
["numReadonlySignerAccounts", getMemoizedU8Decoder()],
|
|
536
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8Decoder()]
|
|
537
|
+
]);
|
|
538
|
+
}
|
|
539
|
+
var memoizedGetInstructionEncoder;
|
|
540
|
+
function getInstructionEncoder() {
|
|
541
|
+
if (!memoizedGetInstructionEncoder) {
|
|
542
|
+
memoizedGetInstructionEncoder = codecsCore.mapEncoder(
|
|
543
|
+
codecsDataStructures.getStructEncoder([
|
|
544
|
+
["programAddressIndex", codecsNumbers.getU8Encoder()],
|
|
545
|
+
["accountIndices", codecsDataStructures.getArrayEncoder(codecsNumbers.getU8Encoder(), { size: codecsNumbers.getShortU16Encoder() })],
|
|
546
|
+
["data", codecsDataStructures.getBytesEncoder({ size: codecsNumbers.getShortU16Encoder() })]
|
|
547
|
+
]),
|
|
548
|
+
// Convert an instruction to have all fields defined
|
|
549
|
+
(instruction) => {
|
|
550
|
+
if (instruction.accountIndices !== void 0 && instruction.data !== void 0) {
|
|
551
|
+
return instruction;
|
|
552
|
+
}
|
|
553
|
+
return {
|
|
554
|
+
...instruction,
|
|
555
|
+
accountIndices: instruction.accountIndices ?? [],
|
|
556
|
+
data: instruction.data ?? new Uint8Array(0)
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
return memoizedGetInstructionEncoder;
|
|
562
|
+
}
|
|
563
|
+
var memoizedGetInstructionDecoder;
|
|
564
|
+
function getInstructionDecoder() {
|
|
565
|
+
if (!memoizedGetInstructionDecoder) {
|
|
566
|
+
memoizedGetInstructionDecoder = codecsCore.mapDecoder(
|
|
567
|
+
codecsDataStructures.getStructDecoder([
|
|
568
|
+
["programAddressIndex", codecsNumbers.getU8Decoder()],
|
|
569
|
+
["accountIndices", codecsDataStructures.getArrayDecoder(codecsNumbers.getU8Decoder(), { size: codecsNumbers.getShortU16Decoder() })],
|
|
570
|
+
["data", codecsDataStructures.getBytesDecoder({ size: codecsNumbers.getShortU16Decoder() })]
|
|
571
|
+
]),
|
|
572
|
+
// Convert an instruction to exclude optional fields if they are empty
|
|
573
|
+
(instruction) => {
|
|
574
|
+
if (instruction.accountIndices.length && instruction.data.byteLength) {
|
|
575
|
+
return instruction;
|
|
576
|
+
}
|
|
577
|
+
const { accountIndices, data, ...rest } = instruction;
|
|
578
|
+
return {
|
|
579
|
+
...rest,
|
|
580
|
+
...accountIndices.length ? { accountIndices } : null,
|
|
581
|
+
...data.byteLength ? { data } : null
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
return memoizedGetInstructionDecoder;
|
|
481
587
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
} : void 0
|
|
499
|
-
)
|
|
500
|
-
],
|
|
501
|
-
[
|
|
502
|
-
"numReadonlyNonSignerAccounts",
|
|
503
|
-
umiSerializers.u8(
|
|
504
|
-
__DEV__ ? {
|
|
505
|
-
description: "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable"
|
|
506
|
-
} : void 0
|
|
507
|
-
)
|
|
508
|
-
]
|
|
509
|
-
],
|
|
510
|
-
__DEV__ ? {
|
|
511
|
-
description: "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses"
|
|
512
|
-
} : void 0
|
|
513
|
-
);
|
|
588
|
+
var VERSION_FLAG_MASK = 128;
|
|
589
|
+
function getTransactionVersionEncoder() {
|
|
590
|
+
return codecsCore.createEncoder({
|
|
591
|
+
getSizeFromValue: (value) => value === "legacy" ? 0 : 1,
|
|
592
|
+
maxSize: 1,
|
|
593
|
+
write: (value, bytes, offset) => {
|
|
594
|
+
if (value === "legacy") {
|
|
595
|
+
return offset;
|
|
596
|
+
}
|
|
597
|
+
if (value < 0 || value > 127) {
|
|
598
|
+
throw new Error(`Transaction version must be in the range [0, 127]. \`${value}\` given.`);
|
|
599
|
+
}
|
|
600
|
+
bytes.set([value | VERSION_FLAG_MASK], offset);
|
|
601
|
+
return offset + 1;
|
|
602
|
+
}
|
|
603
|
+
});
|
|
514
604
|
}
|
|
515
|
-
function
|
|
516
|
-
return
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
[
|
|
539
|
-
"data",
|
|
540
|
-
umiSerializers.bytes({
|
|
541
|
-
description: __DEV__ ? "An optional buffer of data passed to the instruction" : "",
|
|
542
|
-
size: umiSerializers.shortU16()
|
|
543
|
-
})
|
|
544
|
-
]
|
|
605
|
+
function getTransactionVersionDecoder() {
|
|
606
|
+
return codecsCore.createDecoder({
|
|
607
|
+
maxSize: 1,
|
|
608
|
+
read: (bytes, offset) => {
|
|
609
|
+
const firstByte = bytes[offset];
|
|
610
|
+
if ((firstByte & VERSION_FLAG_MASK) === 0) {
|
|
611
|
+
return ["legacy", offset];
|
|
612
|
+
} else {
|
|
613
|
+
const version = firstByte ^ VERSION_FLAG_MASK;
|
|
614
|
+
return [version, offset + 1];
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// src/serializers/message.ts
|
|
621
|
+
function getCompiledMessageLegacyEncoder() {
|
|
622
|
+
return codecsDataStructures.getStructEncoder(getPreludeStructEncoderTuple());
|
|
623
|
+
}
|
|
624
|
+
function getCompiledMessageVersionedEncoder() {
|
|
625
|
+
return codecsCore.mapEncoder(
|
|
626
|
+
codecsDataStructures.getStructEncoder([
|
|
627
|
+
...getPreludeStructEncoderTuple(),
|
|
628
|
+
["addressTableLookups", getAddressTableLookupArrayEncoder()]
|
|
545
629
|
]),
|
|
546
630
|
(value) => {
|
|
547
|
-
if (value.
|
|
631
|
+
if (value.version === "legacy") {
|
|
548
632
|
return value;
|
|
549
633
|
}
|
|
550
634
|
return {
|
|
551
635
|
...value,
|
|
552
|
-
|
|
553
|
-
data: value.data ?? new Uint8Array(0)
|
|
636
|
+
addressTableLookups: value.addressTableLookups ?? []
|
|
554
637
|
};
|
|
638
|
+
}
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
function getPreludeStructEncoderTuple() {
|
|
642
|
+
return [
|
|
643
|
+
["version", getTransactionVersionEncoder()],
|
|
644
|
+
["header", getMessageHeaderEncoder()],
|
|
645
|
+
["staticAccounts", codecsDataStructures.getArrayEncoder(addresses.getAddressEncoder(), { size: codecsNumbers.getShortU16Encoder() })],
|
|
646
|
+
["lifetimeToken", codecsStrings.getStringEncoder({ encoding: codecsStrings.getBase58Encoder(), size: 32 })],
|
|
647
|
+
["instructions", codecsDataStructures.getArrayEncoder(getInstructionEncoder(), { size: codecsNumbers.getShortU16Encoder() })]
|
|
648
|
+
];
|
|
649
|
+
}
|
|
650
|
+
function getPreludeStructDecoderTuple() {
|
|
651
|
+
return [
|
|
652
|
+
["version", getTransactionVersionDecoder()],
|
|
653
|
+
["header", getMessageHeaderDecoder()],
|
|
654
|
+
["staticAccounts", codecsDataStructures.getArrayDecoder(addresses.getAddressDecoder(), { size: codecsNumbers.getShortU16Decoder() })],
|
|
655
|
+
["lifetimeToken", codecsStrings.getStringDecoder({ encoding: codecsStrings.getBase58Decoder(), size: 32 })],
|
|
656
|
+
["instructions", codecsDataStructures.getArrayDecoder(getInstructionDecoder(), { size: codecsNumbers.getShortU16Decoder() })],
|
|
657
|
+
["addressTableLookups", getAddressTableLookupArrayDecoder()]
|
|
658
|
+
];
|
|
659
|
+
}
|
|
660
|
+
function getAddressTableLookupArrayEncoder() {
|
|
661
|
+
return codecsDataStructures.getArrayEncoder(getAddressTableLookupEncoder(), { size: codecsNumbers.getShortU16Encoder() });
|
|
662
|
+
}
|
|
663
|
+
function getAddressTableLookupArrayDecoder() {
|
|
664
|
+
return codecsDataStructures.getArrayDecoder(getAddressTableLookupDecoder(), { size: codecsNumbers.getShortU16Decoder() });
|
|
665
|
+
}
|
|
666
|
+
function getCompiledMessageEncoder() {
|
|
667
|
+
return codecsCore.createEncoder({
|
|
668
|
+
getSizeFromValue: (compiledMessage) => {
|
|
669
|
+
if (compiledMessage.version === "legacy") {
|
|
670
|
+
return getCompiledMessageLegacyEncoder().getSizeFromValue(compiledMessage);
|
|
671
|
+
} else {
|
|
672
|
+
return getCompiledMessageVersionedEncoder().getSizeFromValue(compiledMessage);
|
|
673
|
+
}
|
|
555
674
|
},
|
|
556
|
-
(
|
|
557
|
-
if (
|
|
558
|
-
return
|
|
675
|
+
write: (compiledMessage, bytes, offset) => {
|
|
676
|
+
if (compiledMessage.version === "legacy") {
|
|
677
|
+
return getCompiledMessageLegacyEncoder().write(compiledMessage, bytes, offset);
|
|
678
|
+
} else {
|
|
679
|
+
return getCompiledMessageVersionedEncoder().write(compiledMessage, bytes, offset);
|
|
559
680
|
}
|
|
560
|
-
const { accountIndices, data, ...rest } = value;
|
|
561
|
-
return {
|
|
562
|
-
...rest,
|
|
563
|
-
...accountIndices.length ? { accountIndices } : null,
|
|
564
|
-
...data.byteLength ? { data } : null
|
|
565
|
-
};
|
|
566
681
|
}
|
|
567
|
-
);
|
|
682
|
+
});
|
|
568
683
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
);
|
|
684
|
+
function getCompiledMessageDecoder() {
|
|
685
|
+
return codecsCore.mapDecoder(codecsDataStructures.getStructDecoder(getPreludeStructDecoderTuple()), ({ addressTableLookups, ...restOfMessage }) => {
|
|
686
|
+
if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
|
|
687
|
+
return restOfMessage;
|
|
688
|
+
}
|
|
689
|
+
return { ...restOfMessage, addressTableLookups };
|
|
690
|
+
});
|
|
576
691
|
}
|
|
577
|
-
function
|
|
578
|
-
return ()
|
|
579
|
-
throw getError("decoder", name);
|
|
580
|
-
};
|
|
692
|
+
function getCompiledMessageCodec() {
|
|
693
|
+
return codecsCore.combineCodec(getCompiledMessageEncoder(), getCompiledMessageDecoder());
|
|
581
694
|
}
|
|
582
695
|
|
|
583
|
-
// src/
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
if ((firstByte & VERSION_FLAG_MASK) === 0) {
|
|
593
|
-
return ["legacy", offset];
|
|
696
|
+
// src/compile-transaction.ts
|
|
697
|
+
function getCompiledTransaction(transaction) {
|
|
698
|
+
const compiledMessage = compileMessage(transaction);
|
|
699
|
+
let signatures;
|
|
700
|
+
if ("signatures" in transaction) {
|
|
701
|
+
signatures = [];
|
|
702
|
+
for (let ii = 0; ii < compiledMessage.header.numSignerAccounts; ii++) {
|
|
703
|
+
signatures[ii] = transaction.signatures[compiledMessage.staticAccounts[ii]] ?? new Uint8Array(Array(64).fill(0));
|
|
704
|
+
}
|
|
594
705
|
} else {
|
|
595
|
-
|
|
596
|
-
return [version, offset + 1];
|
|
706
|
+
signatures = Array(compiledMessage.header.numSignerAccounts).fill(new Uint8Array(Array(64).fill(0)));
|
|
597
707
|
}
|
|
708
|
+
return {
|
|
709
|
+
compiledMessage,
|
|
710
|
+
signatures
|
|
711
|
+
};
|
|
598
712
|
}
|
|
599
|
-
function
|
|
600
|
-
|
|
601
|
-
|
|
713
|
+
function getAccountMetas(message) {
|
|
714
|
+
const { header } = message;
|
|
715
|
+
const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
|
|
716
|
+
const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
|
|
717
|
+
const accountMetas = [];
|
|
718
|
+
let accountIndex = 0;
|
|
719
|
+
for (let i = 0; i < numWritableSignerAccounts; i++) {
|
|
720
|
+
accountMetas.push({
|
|
721
|
+
address: message.staticAccounts[accountIndex],
|
|
722
|
+
role: AccountRole.WRITABLE_SIGNER
|
|
723
|
+
});
|
|
724
|
+
accountIndex++;
|
|
602
725
|
}
|
|
603
|
-
|
|
604
|
-
|
|
726
|
+
for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
|
|
727
|
+
accountMetas.push({
|
|
728
|
+
address: message.staticAccounts[accountIndex],
|
|
729
|
+
role: AccountRole.READONLY_SIGNER
|
|
730
|
+
});
|
|
731
|
+
accountIndex++;
|
|
732
|
+
}
|
|
733
|
+
for (let i = 0; i < numWritableNonSignerAccounts; i++) {
|
|
734
|
+
accountMetas.push({
|
|
735
|
+
address: message.staticAccounts[accountIndex],
|
|
736
|
+
role: AccountRole.WRITABLE
|
|
737
|
+
});
|
|
738
|
+
accountIndex++;
|
|
605
739
|
}
|
|
606
|
-
|
|
740
|
+
for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
|
|
741
|
+
accountMetas.push({
|
|
742
|
+
address: message.staticAccounts[accountIndex],
|
|
743
|
+
role: AccountRole.READONLY
|
|
744
|
+
});
|
|
745
|
+
accountIndex++;
|
|
746
|
+
}
|
|
747
|
+
return accountMetas;
|
|
607
748
|
}
|
|
608
|
-
function
|
|
749
|
+
function convertInstruction(instruction, accountMetas) {
|
|
750
|
+
const programAddress = accountMetas[instruction.programAddressIndex]?.address;
|
|
751
|
+
if (!programAddress) {
|
|
752
|
+
throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
|
|
753
|
+
}
|
|
754
|
+
const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
|
|
755
|
+
const { data } = instruction;
|
|
609
756
|
return {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
757
|
+
programAddress,
|
|
758
|
+
...accounts && accounts.length ? { accounts } : {},
|
|
759
|
+
...data && data.length ? { data } : {}
|
|
613
760
|
};
|
|
614
761
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
};
|
|
622
|
-
function serialize2(compiledMessage) {
|
|
623
|
-
if (compiledMessage.version === "legacy") {
|
|
624
|
-
return umiSerializers.struct(getPreludeStructSerializerTuple()).serialize(compiledMessage);
|
|
762
|
+
function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
|
|
763
|
+
if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
764
|
+
return {
|
|
765
|
+
blockhash: messageLifetimeToken,
|
|
766
|
+
lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
|
|
767
|
+
// U64 MAX
|
|
768
|
+
};
|
|
625
769
|
} else {
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
return {
|
|
636
|
-
...value,
|
|
637
|
-
addressTableLookups: value.addressTableLookups ?? []
|
|
638
|
-
};
|
|
639
|
-
}
|
|
640
|
-
).serialize(compiledMessage);
|
|
770
|
+
const nonceAccountAddress = firstInstruction.accounts[0].address;
|
|
771
|
+
addresses.assertIsAddress(nonceAccountAddress);
|
|
772
|
+
const nonceAuthorityAddress = firstInstruction.accounts[2].address;
|
|
773
|
+
addresses.assertIsAddress(nonceAuthorityAddress);
|
|
774
|
+
return {
|
|
775
|
+
nonce: messageLifetimeToken,
|
|
776
|
+
nonceAccountAddress,
|
|
777
|
+
nonceAuthorityAddress
|
|
778
|
+
};
|
|
641
779
|
}
|
|
642
780
|
}
|
|
643
|
-
function
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
]
|
|
781
|
+
function convertSignatures(compiledTransaction) {
|
|
782
|
+
const {
|
|
783
|
+
compiledMessage: { staticAccounts },
|
|
784
|
+
signatures
|
|
785
|
+
} = compiledTransaction;
|
|
786
|
+
return signatures.reduce((acc, sig, index) => {
|
|
787
|
+
const allZeros = sig.every((byte) => byte === 0);
|
|
788
|
+
if (allZeros)
|
|
789
|
+
return acc;
|
|
790
|
+
const address = staticAccounts[index];
|
|
791
|
+
return { ...acc, [address]: sig };
|
|
792
|
+
}, {});
|
|
793
|
+
}
|
|
794
|
+
function decompileTransaction(compiledTransaction, lastValidBlockHeight) {
|
|
795
|
+
const { compiledMessage } = compiledTransaction;
|
|
796
|
+
if ("addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups.length > 0) {
|
|
797
|
+
throw new Error("Cannot convert transaction with addressTableLookups");
|
|
798
|
+
}
|
|
799
|
+
const feePayer = compiledMessage.staticAccounts[0];
|
|
800
|
+
if (!feePayer)
|
|
801
|
+
throw new Error("No fee payer set in CompiledTransaction");
|
|
802
|
+
const accountMetas = getAccountMetas(compiledMessage);
|
|
803
|
+
const instructions = compiledMessage.instructions.map(
|
|
804
|
+
(compiledInstruction) => convertInstruction(compiledInstruction, accountMetas)
|
|
805
|
+
);
|
|
806
|
+
const firstInstruction = instructions[0];
|
|
807
|
+
const lifetimeConstraint = getLifetimeConstraint(
|
|
808
|
+
compiledMessage.lifetimeToken,
|
|
809
|
+
firstInstruction,
|
|
810
|
+
lastValidBlockHeight
|
|
811
|
+
);
|
|
812
|
+
const signatures = convertSignatures(compiledTransaction);
|
|
813
|
+
return functional.pipe(
|
|
814
|
+
createTransaction({ version: compiledMessage.version }),
|
|
815
|
+
(tx) => setTransactionFeePayer(feePayer, tx),
|
|
816
|
+
(tx) => instructions.reduce((acc, instruction) => {
|
|
817
|
+
return appendTransactionInstruction(instruction, acc);
|
|
818
|
+
}, tx),
|
|
819
|
+
(tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
|
|
820
|
+
(tx) => compiledTransaction.signatures.length ? { ...tx, signatures } : tx
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
// src/serializers/transaction.ts
|
|
825
|
+
function getCompiledTransactionEncoder() {
|
|
826
|
+
return codecsDataStructures.getStructEncoder([
|
|
827
|
+
["signatures", codecsDataStructures.getArrayEncoder(codecsDataStructures.getBytesEncoder({ size: 64 }), { size: codecsNumbers.getShortU16Encoder() })],
|
|
828
|
+
["compiledMessage", getCompiledMessageEncoder()]
|
|
829
|
+
]);
|
|
830
|
+
}
|
|
831
|
+
function getCompiledTransactionDecoder() {
|
|
832
|
+
return codecsDataStructures.getStructDecoder([
|
|
654
833
|
[
|
|
655
|
-
"
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
encoding: umiSerializers.base58,
|
|
659
|
-
size: 32
|
|
834
|
+
"signatures",
|
|
835
|
+
codecsDataStructures.getArrayDecoder(codecsDataStructures.getBytesDecoder({ size: 64 }), {
|
|
836
|
+
size: codecsNumbers.getShortU16Decoder()
|
|
660
837
|
})
|
|
661
838
|
],
|
|
662
|
-
[
|
|
663
|
-
|
|
664
|
-
umiSerializers.array(getInstructionCodec(), {
|
|
665
|
-
description: __DEV__ ? "A compact-array of instructions belonging to this transaction" : "",
|
|
666
|
-
size: umiSerializers.shortU16()
|
|
667
|
-
})
|
|
668
|
-
]
|
|
669
|
-
];
|
|
670
|
-
}
|
|
671
|
-
function getAddressTableLookupsSerializer() {
|
|
672
|
-
return umiSerializers.array(getAddressTableLookupCodec(), {
|
|
673
|
-
...__DEV__ ? { description: "A compact array of address table lookups belonging to this transaction" } : null,
|
|
674
|
-
size: umiSerializers.shortU16()
|
|
675
|
-
});
|
|
839
|
+
["compiledMessage", getCompiledMessageDecoder()]
|
|
840
|
+
]);
|
|
676
841
|
}
|
|
677
|
-
function
|
|
678
|
-
return
|
|
679
|
-
...BASE_CONFIG2,
|
|
680
|
-
deserialize: getUnimplementedDecoder("CompiledMessage"),
|
|
681
|
-
serialize: serialize2
|
|
682
|
-
};
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
// src/signatures.ts
|
|
686
|
-
function assertIsTransactionSignature(putativeTransactionSignature) {
|
|
687
|
-
try {
|
|
688
|
-
if (
|
|
689
|
-
// Lowest value (64 bytes of zeroes)
|
|
690
|
-
putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
|
|
691
|
-
putativeTransactionSignature.length > 88
|
|
692
|
-
) {
|
|
693
|
-
throw new Error("Expected input string to decode to a byte array of length 64.");
|
|
694
|
-
}
|
|
695
|
-
const bytes3 = umiSerializers.base58.serialize(putativeTransactionSignature);
|
|
696
|
-
const numBytes = bytes3.byteLength;
|
|
697
|
-
if (numBytes !== 64) {
|
|
698
|
-
throw new Error(`Expected input string to decode to a byte array of length 64. Actual length: ${numBytes}`);
|
|
699
|
-
}
|
|
700
|
-
} catch (e) {
|
|
701
|
-
throw new Error(`\`${putativeTransactionSignature}\` is not a transaction signature`, {
|
|
702
|
-
cause: e
|
|
703
|
-
});
|
|
704
|
-
}
|
|
842
|
+
function getTransactionEncoder() {
|
|
843
|
+
return codecsCore.mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
|
|
705
844
|
}
|
|
706
|
-
function
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
) {
|
|
712
|
-
return false;
|
|
713
|
-
}
|
|
714
|
-
const bytes3 = umiSerializers.base58.serialize(putativeTransactionSignature);
|
|
715
|
-
const numBytes = bytes3.byteLength;
|
|
716
|
-
if (numBytes !== 64) {
|
|
717
|
-
return false;
|
|
718
|
-
}
|
|
719
|
-
return true;
|
|
845
|
+
function getTransactionDecoder(lastValidBlockHeight) {
|
|
846
|
+
return codecsCore.mapDecoder(
|
|
847
|
+
getCompiledTransactionDecoder(),
|
|
848
|
+
(compiledTransaction) => decompileTransaction(compiledTransaction, lastValidBlockHeight)
|
|
849
|
+
);
|
|
720
850
|
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
const signature = await keys.signBytes(secretKey, wireMessageBytes);
|
|
724
|
-
return signature;
|
|
851
|
+
function getTransactionCodec(lastValidBlockHeight) {
|
|
852
|
+
return codecsCore.combineCodec(getTransactionEncoder(), getTransactionDecoder(lastValidBlockHeight));
|
|
725
853
|
}
|
|
854
|
+
var base58Decoder;
|
|
726
855
|
function getSignatureFromTransaction(transaction) {
|
|
727
|
-
|
|
728
|
-
|
|
856
|
+
if (!base58Decoder)
|
|
857
|
+
base58Decoder = codecsStrings.getBase58Decoder();
|
|
858
|
+
const signatureBytes = transaction.signatures[transaction.feePayer];
|
|
859
|
+
if (!signatureBytes) {
|
|
729
860
|
throw new Error(
|
|
730
861
|
"Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
|
|
731
862
|
);
|
|
732
863
|
}
|
|
733
|
-
|
|
864
|
+
const transactionSignature = base58Decoder.decode(signatureBytes);
|
|
865
|
+
return transactionSignature;
|
|
734
866
|
}
|
|
735
|
-
async function
|
|
867
|
+
async function partiallySignTransaction(keyPairs, transaction) {
|
|
736
868
|
const compiledMessage = compileMessage(transaction);
|
|
737
869
|
const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
|
|
870
|
+
const wireMessageBytes = getCompiledMessageEncoder().encode(compiledMessage);
|
|
738
871
|
const publicKeySignaturePairs = await Promise.all(
|
|
739
872
|
keyPairs.map(
|
|
740
|
-
(keyPair) => Promise.all([
|
|
741
|
-
addresses.getAddressFromPublicKey(keyPair.publicKey),
|
|
742
|
-
getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
|
|
743
|
-
])
|
|
873
|
+
(keyPair) => Promise.all([addresses.getAddressFromPublicKey(keyPair.publicKey), keys.signBytes(keyPair.privateKey, wireMessageBytes)])
|
|
744
874
|
)
|
|
745
875
|
);
|
|
746
876
|
for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
|
|
@@ -753,77 +883,45 @@ async function signTransaction(keyPairs, transaction) {
|
|
|
753
883
|
Object.freeze(out);
|
|
754
884
|
return out;
|
|
755
885
|
}
|
|
756
|
-
function
|
|
757
|
-
|
|
758
|
-
|
|
886
|
+
async function signTransaction(keyPairs, transaction) {
|
|
887
|
+
const out = await partiallySignTransaction(keyPairs, transaction);
|
|
888
|
+
assertTransactionIsFullySigned(out);
|
|
889
|
+
Object.freeze(out);
|
|
890
|
+
return out;
|
|
759
891
|
}
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
signatures = [];
|
|
767
|
-
for (let ii = 0; ii < compiledMessage.header.numSignerAccounts; ii++) {
|
|
768
|
-
signatures[ii] = transaction.signatures[compiledMessage.staticAccounts[ii]] ?? new Uint8Array(Array(64).fill(0));
|
|
892
|
+
function assertTransactionIsFullySigned(transaction) {
|
|
893
|
+
const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
|
|
894
|
+
const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
|
|
895
|
+
requiredSigners.forEach((address) => {
|
|
896
|
+
if (!transaction.signatures[address]) {
|
|
897
|
+
throw new Error(`Transaction is missing signature for address \`${address}\``);
|
|
769
898
|
}
|
|
770
|
-
}
|
|
771
|
-
signatures = Array(compiledMessage.header.numSignerAccounts).fill(new Uint8Array(Array(64).fill(0)));
|
|
772
|
-
}
|
|
773
|
-
return {
|
|
774
|
-
compiledMessage,
|
|
775
|
-
signatures
|
|
776
|
-
};
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
// src/serializers/transaction.ts
|
|
780
|
-
var BASE_CONFIG3 = {
|
|
781
|
-
description: __DEV__ ? "The wire format of a Solana transaction" : "",
|
|
782
|
-
fixedSize: null,
|
|
783
|
-
maxSize: null
|
|
784
|
-
};
|
|
785
|
-
function serialize3(transaction) {
|
|
786
|
-
const compiledTransaction = getCompiledTransaction(transaction);
|
|
787
|
-
return umiSerializers.struct([
|
|
788
|
-
[
|
|
789
|
-
"signatures",
|
|
790
|
-
umiSerializers.array(umiSerializers.bytes({ size: 64 }), {
|
|
791
|
-
...__DEV__ ? { description: "A compact array of 64-byte, base-64 encoded Ed25519 signatures" } : null,
|
|
792
|
-
size: umiSerializers.shortU16()
|
|
793
|
-
})
|
|
794
|
-
],
|
|
795
|
-
["compiledMessage", getCompiledMessageEncoder()]
|
|
796
|
-
]).serialize(compiledTransaction);
|
|
797
|
-
}
|
|
798
|
-
function getTransactionEncoder() {
|
|
799
|
-
return {
|
|
800
|
-
...BASE_CONFIG3,
|
|
801
|
-
deserialize: getUnimplementedDecoder("CompiledMessage"),
|
|
802
|
-
serialize: serialize3
|
|
803
|
-
};
|
|
899
|
+
});
|
|
804
900
|
}
|
|
805
|
-
|
|
806
|
-
// src/wire-transaction.ts
|
|
807
901
|
function getBase64EncodedWireTransaction(transaction) {
|
|
808
|
-
const wireTransactionBytes = getTransactionEncoder().
|
|
809
|
-
|
|
810
|
-
return btoa(String.fromCharCode(...wireTransactionBytes));
|
|
811
|
-
}
|
|
902
|
+
const wireTransactionBytes = getTransactionEncoder().encode(transaction);
|
|
903
|
+
return codecsStrings.getBase64Decoder().decode(wireTransactionBytes);
|
|
812
904
|
}
|
|
813
905
|
|
|
814
906
|
exports.appendTransactionInstruction = appendTransactionInstruction;
|
|
815
907
|
exports.assertIsBlockhash = assertIsBlockhash;
|
|
816
908
|
exports.assertIsDurableNonceTransaction = assertIsDurableNonceTransaction;
|
|
817
|
-
exports.
|
|
909
|
+
exports.assertIsTransactionWithBlockhashLifetime = assertIsTransactionWithBlockhashLifetime;
|
|
910
|
+
exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
|
|
911
|
+
exports.compileMessage = compileMessage;
|
|
818
912
|
exports.createTransaction = createTransaction;
|
|
819
913
|
exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
|
|
914
|
+
exports.getCompiledMessageCodec = getCompiledMessageCodec;
|
|
915
|
+
exports.getCompiledMessageDecoder = getCompiledMessageDecoder;
|
|
916
|
+
exports.getCompiledMessageEncoder = getCompiledMessageEncoder;
|
|
820
917
|
exports.getSignatureFromTransaction = getSignatureFromTransaction;
|
|
821
|
-
exports.
|
|
918
|
+
exports.getTransactionCodec = getTransactionCodec;
|
|
919
|
+
exports.getTransactionDecoder = getTransactionDecoder;
|
|
920
|
+
exports.getTransactionEncoder = getTransactionEncoder;
|
|
921
|
+
exports.isAdvanceNonceAccountInstruction = isAdvanceNonceAccountInstruction;
|
|
922
|
+
exports.partiallySignTransaction = partiallySignTransaction;
|
|
822
923
|
exports.prependTransactionInstruction = prependTransactionInstruction;
|
|
823
924
|
exports.setTransactionFeePayer = setTransactionFeePayer;
|
|
824
925
|
exports.setTransactionLifetimeUsingBlockhash = setTransactionLifetimeUsingBlockhash;
|
|
825
926
|
exports.setTransactionLifetimeUsingDurableNonce = setTransactionLifetimeUsingDurableNonce;
|
|
826
927
|
exports.signTransaction = signTransaction;
|
|
827
|
-
exports.transactionSignature = transactionSignature;
|
|
828
|
-
//# sourceMappingURL=out.js.map
|
|
829
|
-
//# sourceMappingURL=index.browser.cjs.map
|