@solana/transactions 2.0.0-experimental.71b920d → 2.0.0-experimental.72efece
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/dist/index.browser.cjs +343 -128
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +335 -130
- package/dist/index.browser.js.map +1 -1
- package/dist/index.development.js +899 -258
- package/dist/index.development.js.map +1 -1
- package/dist/index.native.js +335 -130
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +343 -128
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +335 -130
- package/dist/index.node.js.map +1 -1
- package/dist/index.production.min.js +16 -6
- package/dist/types/accounts.d.ts +2 -2
- package/dist/types/blockhash.d.ts +9 -1
- package/dist/types/compile-address-table-lookups.d.ts +1 -1
- package/dist/types/compile-instructions.d.ts +1 -1
- package/dist/types/compile-static-accounts.d.ts +1 -1
- package/dist/types/compile-transaction.d.ts +11 -0
- package/dist/types/durable-nonce.d.ts +20 -7
- package/dist/types/fee-payer.d.ts +3 -2
- package/dist/types/index.d.ts +2 -0
- package/dist/types/serializers/header.d.ts +4 -2
- package/dist/types/serializers/index.d.ts +2 -0
- package/dist/types/serializers/transaction-version.d.ts +4 -4
- package/dist/types/serializers/transaction.d.ts +6 -0
- package/dist/types/signatures.d.ts +13 -6
- package/dist/types/types.d.ts +7 -0
- package/dist/types/unsigned-transaction.d.ts +4 -0
- package/dist/types/wire-transaction.d.ts +6 -0
- package/package.json +23 -22
package/dist/index.native.js
CHANGED
|
@@ -1,77 +1,68 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { base58, struct, array, bytes, shortU16, mapSerializer, string, u8 } from '@metaplex-foundation/umi-serializers';
|
|
2
|
+
import { getAddressFromPublicKey, getAddressComparator, getAddressCodec } from '@solana/addresses';
|
|
3
|
+
import { getStructCodec } from '@solana/codecs-data-structures';
|
|
4
|
+
import { getU8Codec } from '@solana/codecs-numbers';
|
|
5
|
+
import { combineCodec } from '@solana/codecs-core';
|
|
6
|
+
import { signBytes } from '@solana/keys';
|
|
3
7
|
|
|
4
8
|
// ../build-scripts/env-shim.ts
|
|
5
9
|
var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
|
|
6
10
|
|
|
7
|
-
// src/
|
|
8
|
-
function
|
|
9
|
-
version
|
|
10
|
-
}) {
|
|
11
|
-
const out = {
|
|
12
|
-
instructions: [],
|
|
13
|
-
version
|
|
14
|
-
};
|
|
15
|
-
Object.freeze(out);
|
|
16
|
-
return out;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// src/fee-payer.ts
|
|
20
|
-
function setTransactionFeePayer(feePayer, transaction) {
|
|
21
|
-
if ("feePayer" in transaction && feePayer === transaction.feePayer) {
|
|
22
|
-
return transaction;
|
|
23
|
-
}
|
|
24
|
-
let out;
|
|
11
|
+
// src/unsigned-transaction.ts
|
|
12
|
+
function getUnsignedTransaction(transaction) {
|
|
25
13
|
if ("signatures" in transaction) {
|
|
26
14
|
const {
|
|
27
15
|
signatures: _,
|
|
28
16
|
// eslint-disable-line @typescript-eslint/no-unused-vars
|
|
29
17
|
...unsignedTransaction
|
|
30
18
|
} = transaction;
|
|
31
|
-
|
|
32
|
-
...unsignedTransaction,
|
|
33
|
-
feePayer
|
|
34
|
-
};
|
|
19
|
+
return unsignedTransaction;
|
|
35
20
|
} else {
|
|
36
|
-
|
|
37
|
-
...transaction,
|
|
38
|
-
feePayer
|
|
39
|
-
};
|
|
21
|
+
return transaction;
|
|
40
22
|
}
|
|
41
|
-
Object.freeze(out);
|
|
42
|
-
return out;
|
|
43
23
|
}
|
|
44
24
|
|
|
45
|
-
// src/
|
|
46
|
-
function
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
25
|
+
// src/blockhash.ts
|
|
26
|
+
function assertIsBlockhash(putativeBlockhash) {
|
|
27
|
+
try {
|
|
28
|
+
if (
|
|
29
|
+
// Lowest value (32 bytes of zeroes)
|
|
30
|
+
putativeBlockhash.length < 32 || // Highest value (32 bytes of 255)
|
|
31
|
+
putativeBlockhash.length > 44
|
|
32
|
+
) {
|
|
33
|
+
throw new Error("Expected input string to decode to a byte array of length 32.");
|
|
34
|
+
}
|
|
35
|
+
const bytes3 = base58.serialize(putativeBlockhash);
|
|
36
|
+
const numBytes = bytes3.byteLength;
|
|
37
|
+
if (numBytes !== 32) {
|
|
38
|
+
throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
|
|
39
|
+
}
|
|
40
|
+
} catch (e) {
|
|
41
|
+
throw new Error(`\`${putativeBlockhash}\` is not a blockhash`, {
|
|
42
|
+
cause: e
|
|
43
|
+
});
|
|
63
44
|
}
|
|
64
|
-
return out;
|
|
65
45
|
}
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
|
|
46
|
+
function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
|
|
47
|
+
if ("lifetimeConstraint" in transaction && transaction.lifetimeConstraint.blockhash === blockhashLifetimeConstraint.blockhash && transaction.lifetimeConstraint.lastValidBlockHeight === blockhashLifetimeConstraint.lastValidBlockHeight) {
|
|
48
|
+
return transaction;
|
|
49
|
+
}
|
|
50
|
+
const out = {
|
|
51
|
+
...getUnsignedTransaction(transaction),
|
|
52
|
+
lifetimeConstraint: blockhashLifetimeConstraint
|
|
53
|
+
};
|
|
69
54
|
Object.freeze(out);
|
|
70
55
|
return out;
|
|
71
56
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
57
|
+
|
|
58
|
+
// src/create-transaction.ts
|
|
59
|
+
function createTransaction({
|
|
60
|
+
version
|
|
61
|
+
}) {
|
|
62
|
+
const out = {
|
|
63
|
+
instructions: [],
|
|
64
|
+
version
|
|
65
|
+
};
|
|
75
66
|
Object.freeze(out);
|
|
76
67
|
return out;
|
|
77
68
|
}
|
|
@@ -98,6 +89,96 @@ function isWritableRole(role) {
|
|
|
98
89
|
function mergeRoles(roleA, roleB) {
|
|
99
90
|
return roleA | roleB;
|
|
100
91
|
}
|
|
92
|
+
|
|
93
|
+
// src/durable-nonce.ts
|
|
94
|
+
var RECENT_BLOCKHASHES_SYSVAR_ADDRESS = "SysvarRecentB1ockHashes11111111111111111111";
|
|
95
|
+
var SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
|
|
96
|
+
function assertIsDurableNonceTransaction(transaction) {
|
|
97
|
+
if (!isDurableNonceTransaction(transaction)) {
|
|
98
|
+
throw new Error("Transaction is not a durable nonce transaction");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress) {
|
|
102
|
+
return {
|
|
103
|
+
accounts: [
|
|
104
|
+
{ address: nonceAccountAddress, role: AccountRole.WRITABLE },
|
|
105
|
+
{
|
|
106
|
+
address: RECENT_BLOCKHASHES_SYSVAR_ADDRESS,
|
|
107
|
+
role: AccountRole.READONLY
|
|
108
|
+
},
|
|
109
|
+
{ address: nonceAuthorityAddress, role: AccountRole.READONLY_SIGNER }
|
|
110
|
+
],
|
|
111
|
+
data: new Uint8Array([4, 0, 0, 0]),
|
|
112
|
+
programAddress: SYSTEM_PROGRAM_ADDRESS
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function isAdvanceNonceAccountInstruction(instruction) {
|
|
116
|
+
return instruction.programAddress === SYSTEM_PROGRAM_ADDRESS && // Test for `AdvanceNonceAccount` instruction data
|
|
117
|
+
instruction.data != null && isAdvanceNonceAccountInstructionData(instruction.data) && // Test for exactly 3 accounts
|
|
118
|
+
instruction.accounts?.length === 3 && // First account is nonce account address
|
|
119
|
+
instruction.accounts[0].address != null && instruction.accounts[0].role === AccountRole.WRITABLE && // Second account is recent blockhashes sysvar
|
|
120
|
+
instruction.accounts[1].address === RECENT_BLOCKHASHES_SYSVAR_ADDRESS && instruction.accounts[1].role === AccountRole.READONLY && // Third account is nonce authority account
|
|
121
|
+
instruction.accounts[2].address != null && instruction.accounts[2].role === AccountRole.READONLY_SIGNER;
|
|
122
|
+
}
|
|
123
|
+
function isAdvanceNonceAccountInstructionData(data) {
|
|
124
|
+
return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;
|
|
125
|
+
}
|
|
126
|
+
function isDurableNonceTransaction(transaction) {
|
|
127
|
+
return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
|
|
128
|
+
}
|
|
129
|
+
function setTransactionLifetimeUsingDurableNonce({
|
|
130
|
+
nonce,
|
|
131
|
+
nonceAccountAddress,
|
|
132
|
+
nonceAuthorityAddress
|
|
133
|
+
}, transaction) {
|
|
134
|
+
const isAlreadyDurableNonceTransaction = isDurableNonceTransaction(transaction);
|
|
135
|
+
if (isAlreadyDurableNonceTransaction && transaction.lifetimeConstraint.nonce === nonce && transaction.instructions[0].accounts[0].address === nonceAccountAddress && transaction.instructions[0].accounts[2].address === nonceAuthorityAddress) {
|
|
136
|
+
return transaction;
|
|
137
|
+
}
|
|
138
|
+
const out = {
|
|
139
|
+
...getUnsignedTransaction(transaction),
|
|
140
|
+
instructions: [
|
|
141
|
+
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
142
|
+
...isAlreadyDurableNonceTransaction ? transaction.instructions.slice(1) : transaction.instructions
|
|
143
|
+
],
|
|
144
|
+
lifetimeConstraint: {
|
|
145
|
+
nonce
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
Object.freeze(out);
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/fee-payer.ts
|
|
153
|
+
function setTransactionFeePayer(feePayer, transaction) {
|
|
154
|
+
if ("feePayer" in transaction && feePayer === transaction.feePayer) {
|
|
155
|
+
return transaction;
|
|
156
|
+
}
|
|
157
|
+
const out = {
|
|
158
|
+
...getUnsignedTransaction(transaction),
|
|
159
|
+
feePayer
|
|
160
|
+
};
|
|
161
|
+
Object.freeze(out);
|
|
162
|
+
return out;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/instructions.ts
|
|
166
|
+
function appendTransactionInstruction(instruction, transaction) {
|
|
167
|
+
const out = {
|
|
168
|
+
...getUnsignedTransaction(transaction),
|
|
169
|
+
instructions: [...transaction.instructions, instruction]
|
|
170
|
+
};
|
|
171
|
+
Object.freeze(out);
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
174
|
+
function prependTransactionInstruction(instruction, transaction) {
|
|
175
|
+
const out = {
|
|
176
|
+
...getUnsignedTransaction(transaction),
|
|
177
|
+
instructions: [instruction, ...transaction.instructions]
|
|
178
|
+
};
|
|
179
|
+
Object.freeze(out);
|
|
180
|
+
return out;
|
|
181
|
+
}
|
|
101
182
|
function upsert(addressMap, address, update) {
|
|
102
183
|
addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
|
|
103
184
|
}
|
|
@@ -150,7 +231,7 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
150
231
|
const shouldReplaceEntry = (
|
|
151
232
|
// Consider using the new LOOKUP_TABLE if its address is different...
|
|
152
233
|
entry.lookupTableAddress !== accountMeta.lookupTableAddress && // ...and sorts before the existing one.
|
|
153
|
-
(addressComparator || (addressComparator =
|
|
234
|
+
(addressComparator || (addressComparator = getAddressComparator()))(
|
|
154
235
|
accountMeta.lookupTableAddress,
|
|
155
236
|
entry.lookupTableAddress
|
|
156
237
|
) < 0
|
|
@@ -256,7 +337,7 @@ function getOrderedAccountsFromAddressMap(addressMap) {
|
|
|
256
337
|
if (leftIsWritable !== isWritableRole(rightEntry.role)) {
|
|
257
338
|
return leftIsWritable ? -1 : 1;
|
|
258
339
|
}
|
|
259
|
-
addressComparator || (addressComparator =
|
|
340
|
+
addressComparator || (addressComparator = getAddressComparator());
|
|
260
341
|
if (leftEntry[TYPE] === 1 /* LOOKUP_TABLE */ && rightEntry[TYPE] === 1 /* LOOKUP_TABLE */ && leftEntry.lookupTableAddress !== rightEntry.lookupTableAddress) {
|
|
261
342
|
return addressComparator(leftEntry.lookupTableAddress, rightEntry.lookupTableAddress);
|
|
262
343
|
} else {
|
|
@@ -285,7 +366,7 @@ function getCompiledAddressTableLookups(orderedAccounts) {
|
|
|
285
366
|
entry.readableIndices.push(account.addressIndex);
|
|
286
367
|
}
|
|
287
368
|
}
|
|
288
|
-
return Object.keys(index).sort(
|
|
369
|
+
return Object.keys(index).sort(getAddressComparator()).map((lookupTableAddress) => ({
|
|
289
370
|
lookupTableAddress,
|
|
290
371
|
...index[lookupTableAddress]
|
|
291
372
|
}));
|
|
@@ -364,12 +445,40 @@ function compileMessage(transaction) {
|
|
|
364
445
|
version: transaction.version
|
|
365
446
|
};
|
|
366
447
|
}
|
|
448
|
+
|
|
449
|
+
// src/compile-transaction.ts
|
|
450
|
+
function getCompiledTransaction(transaction) {
|
|
451
|
+
const compiledMessage = compileMessage(transaction);
|
|
452
|
+
let signatures;
|
|
453
|
+
if ("signatures" in transaction) {
|
|
454
|
+
signatures = [];
|
|
455
|
+
for (let ii = 0; ii < compiledMessage.header.numSignerAccounts; ii++) {
|
|
456
|
+
signatures[ii] = transaction.signatures[compiledMessage.staticAccounts[ii]] ?? new Uint8Array(Array(64).fill(0));
|
|
457
|
+
}
|
|
458
|
+
} else {
|
|
459
|
+
signatures = Array(compiledMessage.header.numSignerAccounts).fill(new Uint8Array(Array(64).fill(0)));
|
|
460
|
+
}
|
|
461
|
+
return {
|
|
462
|
+
compiledMessage,
|
|
463
|
+
signatures
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
function addressSerializerCompat(compat) {
|
|
467
|
+
const codec = getAddressCodec();
|
|
468
|
+
return {
|
|
469
|
+
description: compat?.description ?? codec.description,
|
|
470
|
+
deserialize: codec.decode,
|
|
471
|
+
fixedSize: codec.fixedSize,
|
|
472
|
+
maxSize: codec.maxSize,
|
|
473
|
+
serialize: codec.encode
|
|
474
|
+
};
|
|
475
|
+
}
|
|
367
476
|
function getAddressTableLookupCodec() {
|
|
368
477
|
return struct(
|
|
369
478
|
[
|
|
370
479
|
[
|
|
371
480
|
"lookupTableAddress",
|
|
372
|
-
|
|
481
|
+
addressSerializerCompat(
|
|
373
482
|
__DEV__ ? {
|
|
374
483
|
description: "The address of the address lookup table account from which instruction addresses should be looked up"
|
|
375
484
|
} : void 0
|
|
@@ -399,37 +508,33 @@ function getAddressTableLookupCodec() {
|
|
|
399
508
|
} : void 0
|
|
400
509
|
);
|
|
401
510
|
}
|
|
511
|
+
var memoizedU8Codec;
|
|
512
|
+
function getMemoizedU8Codec() {
|
|
513
|
+
if (!memoizedU8Codec)
|
|
514
|
+
memoizedU8Codec = getU8Codec();
|
|
515
|
+
return memoizedU8Codec;
|
|
516
|
+
}
|
|
517
|
+
function getMemoizedU8CodecDescription(description) {
|
|
518
|
+
const codec = getMemoizedU8Codec();
|
|
519
|
+
return {
|
|
520
|
+
...codec,
|
|
521
|
+
description: description ?? codec.description
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
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;
|
|
525
|
+
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;
|
|
526
|
+
var numReadonlyNonSignerAccountsDescription = __DEV__ ? "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable" : void 0;
|
|
527
|
+
var messageHeaderDescription = __DEV__ ? "The transaction message header containing counts of the signer, readonly-signer, and readonly-nonsigner account addresses" : void 0;
|
|
402
528
|
function getMessageHeaderCodec() {
|
|
403
|
-
return
|
|
529
|
+
return getStructCodec(
|
|
404
530
|
[
|
|
405
|
-
[
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
__DEV__ ? {
|
|
409
|
-
description: "The expected number of addresses in the static address list belonging to accounts that are required to sign this transaction"
|
|
410
|
-
} : void 0
|
|
411
|
-
)
|
|
412
|
-
],
|
|
413
|
-
[
|
|
414
|
-
"numReadonlySignerAccounts",
|
|
415
|
-
u8(
|
|
416
|
-
__DEV__ ? {
|
|
417
|
-
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"
|
|
418
|
-
} : void 0
|
|
419
|
-
)
|
|
420
|
-
],
|
|
421
|
-
[
|
|
422
|
-
"numReadonlyNonSignerAccounts",
|
|
423
|
-
u8(
|
|
424
|
-
__DEV__ ? {
|
|
425
|
-
description: "The expected number of addresses in the static address list belonging to accounts that are neither signers, nor writable"
|
|
426
|
-
} : void 0
|
|
427
|
-
)
|
|
428
|
-
]
|
|
531
|
+
["numSignerAccounts", getMemoizedU8CodecDescription(numSignerAccountsDescription)],
|
|
532
|
+
["numReadonlySignerAccounts", getMemoizedU8CodecDescription(numReadonlySignerAccountsDescription)],
|
|
533
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8CodecDescription(numReadonlyNonSignerAccountsDescription)]
|
|
429
534
|
],
|
|
430
|
-
|
|
431
|
-
description:
|
|
432
|
-
}
|
|
535
|
+
{
|
|
536
|
+
description: messageHeaderDescription
|
|
537
|
+
}
|
|
433
538
|
);
|
|
434
539
|
}
|
|
435
540
|
function getInstructionCodec() {
|
|
@@ -444,7 +549,7 @@ function getInstructionCodec() {
|
|
|
444
549
|
)
|
|
445
550
|
],
|
|
446
551
|
[
|
|
447
|
-
"
|
|
552
|
+
"accountIndices",
|
|
448
553
|
array(
|
|
449
554
|
u8({
|
|
450
555
|
description: __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : ""
|
|
@@ -464,51 +569,36 @@ function getInstructionCodec() {
|
|
|
464
569
|
]
|
|
465
570
|
]),
|
|
466
571
|
(value) => {
|
|
467
|
-
if (value.
|
|
572
|
+
if (value.accountIndices !== void 0 && value.data !== void 0) {
|
|
468
573
|
return value;
|
|
469
574
|
}
|
|
470
575
|
return {
|
|
471
576
|
...value,
|
|
472
|
-
|
|
577
|
+
accountIndices: value.accountIndices ?? [],
|
|
473
578
|
data: value.data ?? new Uint8Array(0)
|
|
474
579
|
};
|
|
475
580
|
},
|
|
476
581
|
(value) => {
|
|
477
|
-
if (value.
|
|
582
|
+
if (value.accountIndices.length && value.data.byteLength) {
|
|
478
583
|
return value;
|
|
479
584
|
}
|
|
480
|
-
const {
|
|
585
|
+
const { accountIndices, data, ...rest } = value;
|
|
481
586
|
return {
|
|
482
587
|
...rest,
|
|
483
|
-
...
|
|
588
|
+
...accountIndices.length ? { accountIndices } : null,
|
|
484
589
|
...data.byteLength ? { data } : null
|
|
485
590
|
};
|
|
486
591
|
}
|
|
487
592
|
);
|
|
488
593
|
}
|
|
489
|
-
|
|
490
|
-
// src/serializers/unimplemented.ts
|
|
491
|
-
function getError(type, name) {
|
|
492
|
-
const functionSuffix = name + type[0].toUpperCase() + type.slice(1);
|
|
493
|
-
return new Error(
|
|
494
|
-
`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}`
|
|
495
|
-
);
|
|
496
|
-
}
|
|
497
|
-
function getUnimplementedDecoder(name) {
|
|
498
|
-
return () => {
|
|
499
|
-
throw getError("decoder", name);
|
|
500
|
-
};
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
// src/serializers/transaction-version.ts
|
|
504
594
|
var VERSION_FLAG_MASK = 128;
|
|
505
595
|
var BASE_CONFIG = {
|
|
506
596
|
description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
|
|
507
597
|
fixedSize: null,
|
|
508
598
|
maxSize: 1
|
|
509
599
|
};
|
|
510
|
-
function
|
|
511
|
-
const firstByte =
|
|
600
|
+
function decode(bytes3, offset = 0) {
|
|
601
|
+
const firstByte = bytes3[offset];
|
|
512
602
|
if ((firstByte & VERSION_FLAG_MASK) === 0) {
|
|
513
603
|
return ["legacy", offset];
|
|
514
604
|
} else {
|
|
@@ -516,7 +606,7 @@ function deserialize(bytes2, offset = 0) {
|
|
|
516
606
|
return [version, offset + 1];
|
|
517
607
|
}
|
|
518
608
|
}
|
|
519
|
-
function
|
|
609
|
+
function encode(value) {
|
|
520
610
|
if (value === "legacy") {
|
|
521
611
|
return new Uint8Array();
|
|
522
612
|
}
|
|
@@ -525,11 +615,32 @@ function serialize(value) {
|
|
|
525
615
|
}
|
|
526
616
|
return new Uint8Array([value | VERSION_FLAG_MASK]);
|
|
527
617
|
}
|
|
528
|
-
function
|
|
618
|
+
function getTransactionVersionDecoder() {
|
|
529
619
|
return {
|
|
530
620
|
...BASE_CONFIG,
|
|
531
|
-
|
|
532
|
-
|
|
621
|
+
decode
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
function getTransactionVersionEncoder() {
|
|
625
|
+
return {
|
|
626
|
+
...BASE_CONFIG,
|
|
627
|
+
encode
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
function getTransactionVersionCodec() {
|
|
631
|
+
return combineCodec(getTransactionVersionEncoder(), getTransactionVersionDecoder());
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// src/serializers/unimplemented.ts
|
|
635
|
+
function getError(type, name) {
|
|
636
|
+
const functionSuffix = name + type[0].toUpperCase() + type.slice(1);
|
|
637
|
+
return new Error(
|
|
638
|
+
`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}`
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
function getUnimplementedDecoder(name) {
|
|
642
|
+
return () => {
|
|
643
|
+
throw getError("decoder", name);
|
|
533
644
|
};
|
|
534
645
|
}
|
|
535
646
|
|
|
@@ -539,7 +650,7 @@ var BASE_CONFIG2 = {
|
|
|
539
650
|
fixedSize: null,
|
|
540
651
|
maxSize: null
|
|
541
652
|
};
|
|
542
|
-
function
|
|
653
|
+
function serialize(compiledMessage) {
|
|
543
654
|
if (compiledMessage.version === "legacy") {
|
|
544
655
|
return struct(getPreludeStructSerializerTuple()).serialize(compiledMessage);
|
|
545
656
|
} else {
|
|
@@ -560,13 +671,22 @@ function serialize2(compiledMessage) {
|
|
|
560
671
|
).serialize(compiledMessage);
|
|
561
672
|
}
|
|
562
673
|
}
|
|
674
|
+
function toSerializer(codec) {
|
|
675
|
+
return {
|
|
676
|
+
description: codec.description,
|
|
677
|
+
deserialize: codec.decode,
|
|
678
|
+
fixedSize: codec.fixedSize,
|
|
679
|
+
maxSize: codec.maxSize,
|
|
680
|
+
serialize: codec.encode
|
|
681
|
+
};
|
|
682
|
+
}
|
|
563
683
|
function getPreludeStructSerializerTuple() {
|
|
564
684
|
return [
|
|
565
|
-
["version", getTransactionVersionCodec()],
|
|
566
|
-
["header", getMessageHeaderCodec()],
|
|
685
|
+
["version", toSerializer(getTransactionVersionCodec())],
|
|
686
|
+
["header", toSerializer(getMessageHeaderCodec())],
|
|
567
687
|
[
|
|
568
688
|
"staticAccounts",
|
|
569
|
-
array(
|
|
689
|
+
array(toSerializer(getAddressCodec()), {
|
|
570
690
|
description: __DEV__ ? "A compact-array of static account addresses belonging to this transaction" : "",
|
|
571
691
|
size: shortU16()
|
|
572
692
|
})
|
|
@@ -598,26 +718,99 @@ function getCompiledMessageEncoder() {
|
|
|
598
718
|
return {
|
|
599
719
|
...BASE_CONFIG2,
|
|
600
720
|
deserialize: getUnimplementedDecoder("CompiledMessage"),
|
|
601
|
-
serialize
|
|
721
|
+
serialize
|
|
602
722
|
};
|
|
603
723
|
}
|
|
604
724
|
|
|
605
|
-
// src/
|
|
725
|
+
// src/serializers/transaction.ts
|
|
726
|
+
var BASE_CONFIG3 = {
|
|
727
|
+
description: __DEV__ ? "The wire format of a Solana transaction" : "",
|
|
728
|
+
fixedSize: null,
|
|
729
|
+
maxSize: null
|
|
730
|
+
};
|
|
731
|
+
function serialize2(transaction) {
|
|
732
|
+
const compiledTransaction = getCompiledTransaction(transaction);
|
|
733
|
+
return struct([
|
|
734
|
+
[
|
|
735
|
+
"signatures",
|
|
736
|
+
array(bytes({ size: 64 }), {
|
|
737
|
+
...__DEV__ ? { description: "A compact array of 64-byte, base-64 encoded Ed25519 signatures" } : null,
|
|
738
|
+
size: shortU16()
|
|
739
|
+
})
|
|
740
|
+
],
|
|
741
|
+
["compiledMessage", getCompiledMessageEncoder()]
|
|
742
|
+
]).serialize(compiledTransaction);
|
|
743
|
+
}
|
|
744
|
+
function getTransactionEncoder() {
|
|
745
|
+
return {
|
|
746
|
+
...BASE_CONFIG3,
|
|
747
|
+
deserialize: getUnimplementedDecoder("CompiledMessage"),
|
|
748
|
+
serialize: serialize2
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
function assertIsTransactionSignature(putativeTransactionSignature) {
|
|
752
|
+
try {
|
|
753
|
+
if (
|
|
754
|
+
// Lowest value (64 bytes of zeroes)
|
|
755
|
+
putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
|
|
756
|
+
putativeTransactionSignature.length > 88
|
|
757
|
+
) {
|
|
758
|
+
throw new Error("Expected input string to decode to a byte array of length 64.");
|
|
759
|
+
}
|
|
760
|
+
const bytes3 = base58.serialize(putativeTransactionSignature);
|
|
761
|
+
const numBytes = bytes3.byteLength;
|
|
762
|
+
if (numBytes !== 64) {
|
|
763
|
+
throw new Error(`Expected input string to decode to a byte array of length 64. Actual length: ${numBytes}`);
|
|
764
|
+
}
|
|
765
|
+
} catch (e) {
|
|
766
|
+
throw new Error(`\`${putativeTransactionSignature}\` is not a transaction signature`, {
|
|
767
|
+
cause: e
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
function isTransactionSignature(putativeTransactionSignature) {
|
|
772
|
+
if (
|
|
773
|
+
// Lowest value (64 bytes of zeroes)
|
|
774
|
+
putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
|
|
775
|
+
putativeTransactionSignature.length > 88
|
|
776
|
+
) {
|
|
777
|
+
return false;
|
|
778
|
+
}
|
|
779
|
+
const bytes3 = base58.serialize(putativeTransactionSignature);
|
|
780
|
+
const numBytes = bytes3.byteLength;
|
|
781
|
+
if (numBytes !== 64) {
|
|
782
|
+
return false;
|
|
783
|
+
}
|
|
784
|
+
return true;
|
|
785
|
+
}
|
|
606
786
|
async function getCompiledMessageSignature(message, secretKey) {
|
|
607
787
|
const wireMessageBytes = getCompiledMessageEncoder().serialize(message);
|
|
608
788
|
const signature = await signBytes(secretKey, wireMessageBytes);
|
|
609
789
|
return signature;
|
|
610
790
|
}
|
|
611
|
-
|
|
791
|
+
function getSignatureFromTransaction(transaction) {
|
|
792
|
+
const signature = transaction.signatures[transaction.feePayer];
|
|
793
|
+
if (!signature) {
|
|
794
|
+
throw new Error(
|
|
795
|
+
"Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
|
|
796
|
+
);
|
|
797
|
+
}
|
|
798
|
+
return signature;
|
|
799
|
+
}
|
|
800
|
+
async function signTransaction(keyPairs, transaction) {
|
|
612
801
|
const compiledMessage = compileMessage(transaction);
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
802
|
+
const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
|
|
803
|
+
const publicKeySignaturePairs = await Promise.all(
|
|
804
|
+
keyPairs.map(
|
|
805
|
+
(keyPair) => Promise.all([
|
|
806
|
+
getAddressFromPublicKey(keyPair.publicKey),
|
|
807
|
+
getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
|
|
808
|
+
])
|
|
809
|
+
)
|
|
810
|
+
);
|
|
811
|
+
for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
|
|
812
|
+
nextSignatures[signerPublicKey] = signature;
|
|
813
|
+
}
|
|
621
814
|
const out = {
|
|
622
815
|
...transaction,
|
|
623
816
|
signatures: nextSignatures
|
|
@@ -625,7 +818,19 @@ async function signTransaction(keyPair, transaction) {
|
|
|
625
818
|
Object.freeze(out);
|
|
626
819
|
return out;
|
|
627
820
|
}
|
|
821
|
+
function transactionSignature(putativeTransactionSignature) {
|
|
822
|
+
assertIsTransactionSignature(putativeTransactionSignature);
|
|
823
|
+
return putativeTransactionSignature;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
// src/wire-transaction.ts
|
|
827
|
+
function getBase64EncodedWireTransaction(transaction) {
|
|
828
|
+
const wireTransactionBytes = getTransactionEncoder().serialize(transaction);
|
|
829
|
+
{
|
|
830
|
+
return btoa(String.fromCharCode(...wireTransactionBytes));
|
|
831
|
+
}
|
|
832
|
+
}
|
|
628
833
|
|
|
629
|
-
export { appendTransactionInstruction, createTransaction, prependTransactionInstruction, setTransactionFeePayer, signTransaction };
|
|
834
|
+
export { appendTransactionInstruction, assertIsBlockhash, assertIsDurableNonceTransaction, assertIsTransactionSignature, createTransaction, getBase64EncodedWireTransaction, getSignatureFromTransaction, getTransactionEncoder, isTransactionSignature, prependTransactionInstruction, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, setTransactionLifetimeUsingDurableNonce, signTransaction, transactionSignature };
|
|
630
835
|
//# sourceMappingURL=out.js.map
|
|
631
836
|
//# sourceMappingURL=index.native.js.map
|