@solana/transactions 2.0.0-experimental.ce145c8 → 2.0.0-experimental.cee6f23
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/README.md +272 -5
- package/dist/index.browser.cjs +412 -322
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +406 -324
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js +406 -324
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +410 -322
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +406 -324
- package/dist/index.node.js.map +1 -1
- package/dist/types/accounts.d.ts +2 -2
- package/dist/types/accounts.d.ts.map +1 -0
- package/dist/types/blockhash.d.ts +4 -3
- 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 +3 -3
- package/dist/types/compile-address-table-lookups.d.ts.map +1 -0
- package/dist/types/compile-header.d.ts +1 -1
- 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 +1 -1
- package/dist/types/compile-lifetime-token.d.ts.map +1 -0
- package/dist/types/compile-static-accounts.d.ts +3 -3
- package/dist/types/compile-static-accounts.d.ts.map +1 -0
- package/dist/types/compile-transaction.d.ts +6 -7
- package/dist/types/compile-transaction.d.ts.map +1 -0
- package/dist/types/create-transaction.d.ts +1 -1
- package/dist/types/create-transaction.d.ts.map +1 -0
- package/dist/types/decompile-transaction.d.ts +13 -0
- package/dist/types/decompile-transaction.d.ts.map +1 -0
- package/dist/types/durable-nonce.d.ts +7 -8
- package/dist/types/durable-nonce.d.ts.map +1 -0
- package/dist/types/fee-payer.d.ts +6 -6
- package/dist/types/fee-payer.d.ts.map +1 -0
- package/dist/types/index.d.ts +12 -9
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/instructions.d.ts +2 -2
- package/dist/types/instructions.d.ts.map +1 -0
- package/dist/types/message.d.ts +6 -10
- package/dist/types/message.d.ts.map +1 -0
- package/dist/types/serializers/address-table-lookup.d.ts +5 -5
- package/dist/types/serializers/address-table-lookup.d.ts.map +1 -0
- package/dist/types/serializers/header.d.ts +5 -5
- package/dist/types/serializers/header.d.ts.map +1 -0
- package/dist/types/serializers/index.d.ts +2 -1
- package/dist/types/serializers/index.d.ts.map +1 -0
- package/dist/types/serializers/instruction.d.ts +5 -5
- package/dist/types/serializers/instruction.d.ts.map +1 -0
- package/dist/types/serializers/message.d.ts +5 -5
- package/dist/types/serializers/message.d.ts.map +1 -0
- package/dist/types/serializers/transaction-version.d.ts +5 -5
- package/dist/types/serializers/transaction-version.d.ts.map +1 -0
- package/dist/types/serializers/transaction.d.ts +9 -5
- package/dist/types/serializers/transaction.d.ts.map +1 -0
- package/dist/types/signatures.d.ts +9 -13
- package/dist/types/signatures.d.ts.map +1 -0
- package/dist/types/types.d.ts +6 -13
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/unsigned-transaction.d.ts +1 -1
- 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 +16 -15
- package/dist/index.development.js +0 -2042
- package/dist/index.development.js.map +0 -1
- package/dist/index.production.min.js +0 -26
- package/dist/types/serializers/unimplemented.d.ts +0 -3
package/dist/index.node.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getAddressFromPublicKey,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { getBase58Encoder, getBase58Decoder, getBase64Decoder, getStringEncoder, getStringDecoder } from '@solana/codecs-strings';
|
|
2
|
+
import { getAddressFromPublicKey, assertIsAddress, getAddressComparator, getAddressEncoder, getAddressDecoder } from '@solana/addresses';
|
|
3
|
+
import { pipe } from '@solana/functional';
|
|
4
|
+
import { createEncoder, mapDecoder, combineCodec, mapEncoder, createDecoder } from '@solana/codecs-core';
|
|
5
|
+
import { getStructDecoder, getArrayDecoder, getBytesDecoder, getStructEncoder, getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';
|
|
6
|
+
import { getShortU16Decoder, getShortU16Encoder, getU8Encoder, getU8Decoder } from '@solana/codecs-numbers';
|
|
6
7
|
import { signBytes } from '@solana/keys';
|
|
7
8
|
|
|
8
|
-
//
|
|
9
|
-
var __DEV__ = /* @__PURE__ */ (() => process["env"].NODE_ENV === "development")();
|
|
9
|
+
// src/blockhash.ts
|
|
10
10
|
|
|
11
11
|
// src/unsigned-transaction.ts
|
|
12
12
|
function getUnsignedTransaction(transaction) {
|
|
@@ -23,7 +23,10 @@ function getUnsignedTransaction(transaction) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// src/blockhash.ts
|
|
26
|
+
var base58Encoder;
|
|
26
27
|
function assertIsBlockhash(putativeBlockhash) {
|
|
28
|
+
if (!base58Encoder)
|
|
29
|
+
base58Encoder = getBase58Encoder();
|
|
27
30
|
try {
|
|
28
31
|
if (
|
|
29
32
|
// Lowest value (32 bytes of zeroes)
|
|
@@ -32,8 +35,8 @@ function assertIsBlockhash(putativeBlockhash) {
|
|
|
32
35
|
) {
|
|
33
36
|
throw new Error("Expected input string to decode to a byte array of length 32.");
|
|
34
37
|
}
|
|
35
|
-
const
|
|
36
|
-
const numBytes =
|
|
38
|
+
const bytes = base58Encoder.encode(putativeBlockhash);
|
|
39
|
+
const numBytes = bytes.byteLength;
|
|
37
40
|
if (numBytes !== 32) {
|
|
38
41
|
throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
|
|
39
42
|
}
|
|
@@ -43,6 +46,22 @@ function assertIsBlockhash(putativeBlockhash) {
|
|
|
43
46
|
});
|
|
44
47
|
}
|
|
45
48
|
}
|
|
49
|
+
function isTransactionWithBlockhashLifetime(transaction) {
|
|
50
|
+
const lifetimeConstraintShapeMatches = "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.blockhash === "string" && typeof transaction.lifetimeConstraint.lastValidBlockHeight === "bigint";
|
|
51
|
+
if (!lifetimeConstraintShapeMatches)
|
|
52
|
+
return false;
|
|
53
|
+
try {
|
|
54
|
+
assertIsBlockhash(transaction.lifetimeConstraint.blockhash);
|
|
55
|
+
return true;
|
|
56
|
+
} catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function assertIsTransactionWithBlockhashLifetime(transaction) {
|
|
61
|
+
if (!isTransactionWithBlockhashLifetime(transaction)) {
|
|
62
|
+
throw new Error("Transaction does not have a blockhash lifetime");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
46
65
|
function setTransactionLifetimeUsingBlockhash(blockhashLifetimeConstraint, transaction) {
|
|
47
66
|
if ("lifetimeConstraint" in transaction && transaction.lifetimeConstraint.blockhash === blockhashLifetimeConstraint.blockhash && transaction.lifetimeConstraint.lastValidBlockHeight === blockhashLifetimeConstraint.lastValidBlockHeight) {
|
|
48
67
|
return transaction;
|
|
@@ -118,7 +137,7 @@ function isAdvanceNonceAccountInstruction(instruction) {
|
|
|
118
137
|
instruction.accounts?.length === 3 && // First account is nonce account address
|
|
119
138
|
instruction.accounts[0].address != null && instruction.accounts[0].role === AccountRole.WRITABLE && // Second account is recent blockhashes sysvar
|
|
120
139
|
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
|
|
140
|
+
instruction.accounts[2].address != null && isSignerRole(instruction.accounts[2].role);
|
|
122
141
|
}
|
|
123
142
|
function isAdvanceNonceAccountInstructionData(data) {
|
|
124
143
|
return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;
|
|
@@ -126,21 +145,38 @@ function isAdvanceNonceAccountInstructionData(data) {
|
|
|
126
145
|
function isDurableNonceTransaction(transaction) {
|
|
127
146
|
return "lifetimeConstraint" in transaction && typeof transaction.lifetimeConstraint.nonce === "string" && transaction.instructions[0] != null && isAdvanceNonceAccountInstruction(transaction.instructions[0]);
|
|
128
147
|
}
|
|
148
|
+
function isAdvanceNonceAccountInstructionForNonce(instruction, nonceAccountAddress, nonceAuthorityAddress) {
|
|
149
|
+
return instruction.accounts[0].address === nonceAccountAddress && instruction.accounts[2].address === nonceAuthorityAddress;
|
|
150
|
+
}
|
|
129
151
|
function setTransactionLifetimeUsingDurableNonce({
|
|
130
152
|
nonce,
|
|
131
153
|
nonceAccountAddress,
|
|
132
154
|
nonceAuthorityAddress
|
|
133
155
|
}, transaction) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
156
|
+
let newInstructions;
|
|
157
|
+
const firstInstruction = transaction.instructions[0];
|
|
158
|
+
if (firstInstruction && isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
159
|
+
if (isAdvanceNonceAccountInstructionForNonce(firstInstruction, nonceAccountAddress, nonceAuthorityAddress)) {
|
|
160
|
+
if (isDurableNonceTransaction(transaction) && transaction.lifetimeConstraint.nonce === nonce) {
|
|
161
|
+
return transaction;
|
|
162
|
+
} else {
|
|
163
|
+
newInstructions = [firstInstruction, ...transaction.instructions.slice(1)];
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
newInstructions = [
|
|
167
|
+
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
168
|
+
...transaction.instructions.slice(1)
|
|
169
|
+
];
|
|
170
|
+
}
|
|
171
|
+
} else {
|
|
172
|
+
newInstructions = [
|
|
173
|
+
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
174
|
+
...transaction.instructions
|
|
175
|
+
];
|
|
137
176
|
}
|
|
138
177
|
const out = {
|
|
139
178
|
...getUnsignedTransaction(transaction),
|
|
140
|
-
instructions:
|
|
141
|
-
createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress),
|
|
142
|
-
...isAlreadyDurableNonceTransaction ? transaction.instructions.slice(1) : transaction.instructions
|
|
143
|
-
],
|
|
179
|
+
instructions: newInstructions,
|
|
144
180
|
lifetimeConstraint: {
|
|
145
181
|
nonce
|
|
146
182
|
}
|
|
@@ -179,6 +215,151 @@ function prependTransactionInstruction(instruction, transaction) {
|
|
|
179
215
|
Object.freeze(out);
|
|
180
216
|
return out;
|
|
181
217
|
}
|
|
218
|
+
|
|
219
|
+
// src/decompile-transaction.ts
|
|
220
|
+
function getAccountMetas(message) {
|
|
221
|
+
const { header } = message;
|
|
222
|
+
const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;
|
|
223
|
+
const numWritableNonSignerAccounts = message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;
|
|
224
|
+
const accountMetas = [];
|
|
225
|
+
let accountIndex = 0;
|
|
226
|
+
for (let i = 0; i < numWritableSignerAccounts; i++) {
|
|
227
|
+
accountMetas.push({
|
|
228
|
+
address: message.staticAccounts[accountIndex],
|
|
229
|
+
role: AccountRole.WRITABLE_SIGNER
|
|
230
|
+
});
|
|
231
|
+
accountIndex++;
|
|
232
|
+
}
|
|
233
|
+
for (let i = 0; i < header.numReadonlySignerAccounts; i++) {
|
|
234
|
+
accountMetas.push({
|
|
235
|
+
address: message.staticAccounts[accountIndex],
|
|
236
|
+
role: AccountRole.READONLY_SIGNER
|
|
237
|
+
});
|
|
238
|
+
accountIndex++;
|
|
239
|
+
}
|
|
240
|
+
for (let i = 0; i < numWritableNonSignerAccounts; i++) {
|
|
241
|
+
accountMetas.push({
|
|
242
|
+
address: message.staticAccounts[accountIndex],
|
|
243
|
+
role: AccountRole.WRITABLE
|
|
244
|
+
});
|
|
245
|
+
accountIndex++;
|
|
246
|
+
}
|
|
247
|
+
for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {
|
|
248
|
+
accountMetas.push({
|
|
249
|
+
address: message.staticAccounts[accountIndex],
|
|
250
|
+
role: AccountRole.READONLY
|
|
251
|
+
});
|
|
252
|
+
accountIndex++;
|
|
253
|
+
}
|
|
254
|
+
return accountMetas;
|
|
255
|
+
}
|
|
256
|
+
function getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress) {
|
|
257
|
+
const compiledAddressTableLookupAddresses = compiledAddressTableLookups.map((l) => l.lookupTableAddress);
|
|
258
|
+
const missing = compiledAddressTableLookupAddresses.filter((a) => addressesByLookupTableAddress[a] === void 0);
|
|
259
|
+
if (missing.length > 0) {
|
|
260
|
+
const missingAddresses = missing.join(", ");
|
|
261
|
+
throw new Error(`Addresses not provided for lookup tables: [${missingAddresses}]`);
|
|
262
|
+
}
|
|
263
|
+
const readOnlyMetas = [];
|
|
264
|
+
const writableMetas = [];
|
|
265
|
+
for (const lookup of compiledAddressTableLookups) {
|
|
266
|
+
const addresses = addressesByLookupTableAddress[lookup.lookupTableAddress];
|
|
267
|
+
const highestIndex = Math.max(...lookup.readableIndices, ...lookup.writableIndices);
|
|
268
|
+
if (highestIndex >= addresses.length) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
`Cannot look up index ${highestIndex} in lookup table [${lookup.lookupTableAddress}]. The lookup table may have been extended since the addresses provided were retrieved.`
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
const readOnlyForLookup = lookup.readableIndices.map((r) => ({
|
|
274
|
+
address: addresses[r],
|
|
275
|
+
addressIndex: r,
|
|
276
|
+
lookupTableAddress: lookup.lookupTableAddress,
|
|
277
|
+
role: AccountRole.READONLY
|
|
278
|
+
}));
|
|
279
|
+
readOnlyMetas.push(...readOnlyForLookup);
|
|
280
|
+
const writableForLookup = lookup.writableIndices.map((w) => ({
|
|
281
|
+
address: addresses[w],
|
|
282
|
+
addressIndex: w,
|
|
283
|
+
lookupTableAddress: lookup.lookupTableAddress,
|
|
284
|
+
role: AccountRole.WRITABLE
|
|
285
|
+
}));
|
|
286
|
+
writableMetas.push(...writableForLookup);
|
|
287
|
+
}
|
|
288
|
+
return [...writableMetas, ...readOnlyMetas];
|
|
289
|
+
}
|
|
290
|
+
function convertInstruction(instruction, accountMetas) {
|
|
291
|
+
const programAddress = accountMetas[instruction.programAddressIndex]?.address;
|
|
292
|
+
if (!programAddress) {
|
|
293
|
+
throw new Error(`Could not find program address at index ${instruction.programAddressIndex}`);
|
|
294
|
+
}
|
|
295
|
+
const accounts = instruction.accountIndices?.map((accountIndex) => accountMetas[accountIndex]);
|
|
296
|
+
const { data } = instruction;
|
|
297
|
+
return {
|
|
298
|
+
programAddress,
|
|
299
|
+
...accounts && accounts.length ? { accounts } : {},
|
|
300
|
+
...data && data.length ? { data } : {}
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
function getLifetimeConstraint(messageLifetimeToken, firstInstruction, lastValidBlockHeight) {
|
|
304
|
+
if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {
|
|
305
|
+
return {
|
|
306
|
+
blockhash: messageLifetimeToken,
|
|
307
|
+
lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
|
|
308
|
+
// U64 MAX
|
|
309
|
+
};
|
|
310
|
+
} else {
|
|
311
|
+
const nonceAccountAddress = firstInstruction.accounts[0].address;
|
|
312
|
+
assertIsAddress(nonceAccountAddress);
|
|
313
|
+
const nonceAuthorityAddress = firstInstruction.accounts[2].address;
|
|
314
|
+
assertIsAddress(nonceAuthorityAddress);
|
|
315
|
+
return {
|
|
316
|
+
nonce: messageLifetimeToken,
|
|
317
|
+
nonceAccountAddress,
|
|
318
|
+
nonceAuthorityAddress
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
function convertSignatures(compiledTransaction) {
|
|
323
|
+
const {
|
|
324
|
+
compiledMessage: { staticAccounts },
|
|
325
|
+
signatures
|
|
326
|
+
} = compiledTransaction;
|
|
327
|
+
return signatures.reduce((acc, sig, index) => {
|
|
328
|
+
const allZeros = sig.every((byte) => byte === 0);
|
|
329
|
+
if (allZeros)
|
|
330
|
+
return acc;
|
|
331
|
+
const address = staticAccounts[index];
|
|
332
|
+
return { ...acc, [address]: sig };
|
|
333
|
+
}, {});
|
|
334
|
+
}
|
|
335
|
+
function decompileTransaction(compiledTransaction, config) {
|
|
336
|
+
const { compiledMessage } = compiledTransaction;
|
|
337
|
+
const feePayer = compiledMessage.staticAccounts[0];
|
|
338
|
+
if (!feePayer)
|
|
339
|
+
throw new Error("No fee payer set in CompiledTransaction");
|
|
340
|
+
const accountMetas = getAccountMetas(compiledMessage);
|
|
341
|
+
const accountLookupMetas = "addressTableLookups" in compiledMessage && compiledMessage.addressTableLookups !== void 0 && compiledMessage.addressTableLookups.length > 0 ? getAddressLookupMetas(compiledMessage.addressTableLookups, config?.addressesByLookupTableAddress ?? {}) : [];
|
|
342
|
+
const transactionMetas = [...accountMetas, ...accountLookupMetas];
|
|
343
|
+
const instructions = compiledMessage.instructions.map(
|
|
344
|
+
(compiledInstruction) => convertInstruction(compiledInstruction, transactionMetas)
|
|
345
|
+
);
|
|
346
|
+
const firstInstruction = instructions[0];
|
|
347
|
+
const lifetimeConstraint = getLifetimeConstraint(
|
|
348
|
+
compiledMessage.lifetimeToken,
|
|
349
|
+
firstInstruction,
|
|
350
|
+
config?.lastValidBlockHeight
|
|
351
|
+
);
|
|
352
|
+
const signatures = convertSignatures(compiledTransaction);
|
|
353
|
+
return pipe(
|
|
354
|
+
createTransaction({ version: compiledMessage.version }),
|
|
355
|
+
(tx) => setTransactionFeePayer(feePayer, tx),
|
|
356
|
+
(tx) => instructions.reduce((acc, instruction) => {
|
|
357
|
+
return appendTransactionInstruction(instruction, acc);
|
|
358
|
+
}, tx),
|
|
359
|
+
(tx) => "blockhash" in lifetimeConstraint ? setTransactionLifetimeUsingBlockhash(lifetimeConstraint, tx) : setTransactionLifetimeUsingDurableNonce(lifetimeConstraint, tx),
|
|
360
|
+
(tx) => Object.keys(signatures).length > 0 ? { ...tx, signatures } : tx
|
|
361
|
+
);
|
|
362
|
+
}
|
|
182
363
|
function upsert(addressMap, address, update) {
|
|
183
364
|
addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });
|
|
184
365
|
}
|
|
@@ -231,7 +412,7 @@ function getAddressMapFromInstructions(feePayer, instructions) {
|
|
|
231
412
|
const shouldReplaceEntry = (
|
|
232
413
|
// Consider using the new LOOKUP_TABLE if its address is different...
|
|
233
414
|
entry.lookupTableAddress !== accountMeta.lookupTableAddress && // ...and sorts before the existing one.
|
|
234
|
-
(addressComparator
|
|
415
|
+
(addressComparator ||= getAddressComparator())(
|
|
235
416
|
accountMeta.lookupTableAddress,
|
|
236
417
|
entry.lookupTableAddress
|
|
237
418
|
) < 0
|
|
@@ -337,7 +518,7 @@ function getOrderedAccountsFromAddressMap(addressMap) {
|
|
|
337
518
|
if (leftIsWritable !== isWritableRole(rightEntry.role)) {
|
|
338
519
|
return leftIsWritable ? -1 : 1;
|
|
339
520
|
}
|
|
340
|
-
addressComparator
|
|
521
|
+
addressComparator ||= getAddressComparator();
|
|
341
522
|
if (leftEntry[TYPE] === 1 /* LOOKUP_TABLE */ && rightEntry[TYPE] === 1 /* LOOKUP_TABLE */ && leftEntry.lookupTableAddress !== rightEntry.lookupTableAddress) {
|
|
342
523
|
return addressComparator(leftEntry.lookupTableAddress, rightEntry.lookupTableAddress);
|
|
343
524
|
} else {
|
|
@@ -350,16 +531,15 @@ function getOrderedAccountsFromAddressMap(addressMap) {
|
|
|
350
531
|
return orderedAccounts;
|
|
351
532
|
}
|
|
352
533
|
function getCompiledAddressTableLookups(orderedAccounts) {
|
|
353
|
-
var _a;
|
|
354
534
|
const index = {};
|
|
355
535
|
for (const account of orderedAccounts) {
|
|
356
536
|
if (!("lookupTableAddress" in account)) {
|
|
357
537
|
continue;
|
|
358
538
|
}
|
|
359
|
-
const entry = index[
|
|
539
|
+
const entry = index[account.lookupTableAddress] ||= {
|
|
360
540
|
readableIndices: [],
|
|
361
541
|
writableIndices: []
|
|
362
|
-
}
|
|
542
|
+
};
|
|
363
543
|
if (account.role === AccountRole.WRITABLE) {
|
|
364
544
|
entry.writableIndices.push(account.addressIndex);
|
|
365
545
|
} else {
|
|
@@ -445,130 +625,68 @@ function compileMessage(transaction) {
|
|
|
445
625
|
version: transaction.version
|
|
446
626
|
};
|
|
447
627
|
}
|
|
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
|
-
var lookupTableAddressDescription = __DEV__ ? "The address of the address lookup table account from which instruction addresses should be looked up" : "lookupTableAddress";
|
|
467
|
-
var writableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as writeable" : "writableIndices";
|
|
468
|
-
var readableIndicesDescription = __DEV__ ? "The indices of the accounts in the lookup table that should be loaded as read-only" : "readableIndices";
|
|
469
|
-
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";
|
|
470
628
|
var memoizedAddressTableLookupEncoder;
|
|
471
629
|
function getAddressTableLookupEncoder() {
|
|
472
630
|
if (!memoizedAddressTableLookupEncoder) {
|
|
473
|
-
memoizedAddressTableLookupEncoder = getStructEncoder(
|
|
631
|
+
memoizedAddressTableLookupEncoder = getStructEncoder([
|
|
632
|
+
["lookupTableAddress", getAddressEncoder()],
|
|
474
633
|
[
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
"writableIndices",
|
|
478
|
-
getArrayEncoder(getU8Encoder(), {
|
|
479
|
-
description: writableIndicesDescription,
|
|
480
|
-
size: getShortU16Encoder()
|
|
481
|
-
})
|
|
482
|
-
],
|
|
483
|
-
[
|
|
484
|
-
"readableIndices",
|
|
485
|
-
getArrayEncoder(getU8Encoder(), {
|
|
486
|
-
description: readableIndicesDescription,
|
|
487
|
-
size: getShortU16Encoder()
|
|
488
|
-
})
|
|
489
|
-
]
|
|
634
|
+
"writableIndices",
|
|
635
|
+
getArrayEncoder(getU8Encoder(), { size: getShortU16Encoder() })
|
|
490
636
|
],
|
|
491
|
-
|
|
492
|
-
|
|
637
|
+
[
|
|
638
|
+
"readableIndices",
|
|
639
|
+
getArrayEncoder(getU8Encoder(), { size: getShortU16Encoder() })
|
|
640
|
+
]
|
|
641
|
+
]);
|
|
493
642
|
}
|
|
494
643
|
return memoizedAddressTableLookupEncoder;
|
|
495
644
|
}
|
|
496
645
|
var memoizedAddressTableLookupDecoder;
|
|
497
646
|
function getAddressTableLookupDecoder() {
|
|
498
647
|
if (!memoizedAddressTableLookupDecoder) {
|
|
499
|
-
memoizedAddressTableLookupDecoder = getStructDecoder(
|
|
500
|
-
[
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
getArrayDecoder(getU8Decoder(), {
|
|
505
|
-
description: writableIndicesDescription,
|
|
506
|
-
size: getShortU16Decoder()
|
|
507
|
-
})
|
|
508
|
-
],
|
|
509
|
-
[
|
|
510
|
-
"readableIndices",
|
|
511
|
-
getArrayDecoder(getU8Decoder(), {
|
|
512
|
-
description: readableIndicesDescription,
|
|
513
|
-
size: getShortU16Decoder()
|
|
514
|
-
})
|
|
515
|
-
]
|
|
516
|
-
],
|
|
517
|
-
{ description: addressTableLookupDescription }
|
|
518
|
-
);
|
|
648
|
+
memoizedAddressTableLookupDecoder = getStructDecoder([
|
|
649
|
+
["lookupTableAddress", getAddressDecoder()],
|
|
650
|
+
["writableIndices", getArrayDecoder(getU8Decoder(), { size: getShortU16Decoder() })],
|
|
651
|
+
["readableIndices", getArrayDecoder(getU8Decoder(), { size: getShortU16Decoder() })]
|
|
652
|
+
]);
|
|
519
653
|
}
|
|
520
654
|
return memoizedAddressTableLookupDecoder;
|
|
521
655
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
[
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
["numReadonlyNonSignerAccounts", getMemoizedU8CodecDescription(numReadonlyNonSignerAccountsDescription)]
|
|
548
|
-
],
|
|
549
|
-
{
|
|
550
|
-
description: messageHeaderDescription
|
|
551
|
-
}
|
|
552
|
-
);
|
|
656
|
+
var memoizedU8Encoder;
|
|
657
|
+
function getMemoizedU8Encoder() {
|
|
658
|
+
if (!memoizedU8Encoder)
|
|
659
|
+
memoizedU8Encoder = getU8Encoder();
|
|
660
|
+
return memoizedU8Encoder;
|
|
661
|
+
}
|
|
662
|
+
var memoizedU8Decoder;
|
|
663
|
+
function getMemoizedU8Decoder() {
|
|
664
|
+
if (!memoizedU8Decoder)
|
|
665
|
+
memoizedU8Decoder = getU8Decoder();
|
|
666
|
+
return memoizedU8Decoder;
|
|
667
|
+
}
|
|
668
|
+
function getMessageHeaderEncoder() {
|
|
669
|
+
return getStructEncoder([
|
|
670
|
+
["numSignerAccounts", getMemoizedU8Encoder()],
|
|
671
|
+
["numReadonlySignerAccounts", getMemoizedU8Encoder()],
|
|
672
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8Encoder()]
|
|
673
|
+
]);
|
|
674
|
+
}
|
|
675
|
+
function getMessageHeaderDecoder() {
|
|
676
|
+
return getStructDecoder([
|
|
677
|
+
["numSignerAccounts", getMemoizedU8Decoder()],
|
|
678
|
+
["numReadonlySignerAccounts", getMemoizedU8Decoder()],
|
|
679
|
+
["numReadonlyNonSignerAccounts", getMemoizedU8Decoder()]
|
|
680
|
+
]);
|
|
553
681
|
}
|
|
554
|
-
var programAddressIndexDescription = __DEV__ ? "The index of the program being called, according to the well-ordered accounts list for this transaction" : "programAddressIndex";
|
|
555
|
-
var accountIndexDescription = __DEV__ ? "The index of an account, according to the well-ordered accounts list for this transaction" : void 0;
|
|
556
|
-
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";
|
|
557
|
-
var dataDescription = __DEV__ ? "An optional buffer of data passed to the instruction" : "data";
|
|
558
682
|
var memoizedGetInstructionEncoder;
|
|
559
683
|
function getInstructionEncoder() {
|
|
560
684
|
if (!memoizedGetInstructionEncoder) {
|
|
561
685
|
memoizedGetInstructionEncoder = mapEncoder(
|
|
562
686
|
getStructEncoder([
|
|
563
|
-
["programAddressIndex", getU8Encoder(
|
|
564
|
-
[
|
|
565
|
-
|
|
566
|
-
getArrayEncoder(getU8Encoder({ description: accountIndexDescription }), {
|
|
567
|
-
description: accountIndicesDescription,
|
|
568
|
-
size: getShortU16Encoder()
|
|
569
|
-
})
|
|
570
|
-
],
|
|
571
|
-
["data", getBytesEncoder({ description: dataDescription, size: getShortU16Encoder() })]
|
|
687
|
+
["programAddressIndex", getU8Encoder()],
|
|
688
|
+
["accountIndices", getArrayEncoder(getU8Encoder(), { size: getShortU16Encoder() })],
|
|
689
|
+
["data", getBytesEncoder({ size: getShortU16Encoder() })]
|
|
572
690
|
]),
|
|
573
691
|
// Convert an instruction to have all fields defined
|
|
574
692
|
(instruction) => {
|
|
@@ -590,15 +708,9 @@ function getInstructionDecoder() {
|
|
|
590
708
|
if (!memoizedGetInstructionDecoder) {
|
|
591
709
|
memoizedGetInstructionDecoder = mapDecoder(
|
|
592
710
|
getStructDecoder([
|
|
593
|
-
["programAddressIndex", getU8Decoder(
|
|
594
|
-
[
|
|
595
|
-
|
|
596
|
-
getArrayDecoder(getU8Decoder({ description: accountIndexDescription }), {
|
|
597
|
-
description: accountIndicesDescription,
|
|
598
|
-
size: getShortU16Decoder()
|
|
599
|
-
})
|
|
600
|
-
],
|
|
601
|
-
["data", getBytesDecoder({ description: dataDescription, size: getShortU16Decoder() })]
|
|
711
|
+
["programAddressIndex", getU8Decoder()],
|
|
712
|
+
["accountIndices", getArrayDecoder(getU8Decoder(), { size: getShortU16Decoder() })],
|
|
713
|
+
["data", getBytesDecoder({ size: getShortU16Decoder() })]
|
|
602
714
|
]),
|
|
603
715
|
// Convert an instruction to exclude optional fields if they are empty
|
|
604
716
|
(instruction) => {
|
|
@@ -616,225 +728,182 @@ function getInstructionDecoder() {
|
|
|
616
728
|
}
|
|
617
729
|
return memoizedGetInstructionDecoder;
|
|
618
730
|
}
|
|
619
|
-
function getInstructionCodec() {
|
|
620
|
-
return combineCodec(getInstructionEncoder(), getInstructionDecoder());
|
|
621
|
-
}
|
|
622
731
|
var VERSION_FLAG_MASK = 128;
|
|
623
|
-
var BASE_CONFIG = {
|
|
624
|
-
description: __DEV__ ? "A single byte that encodes the version of the transaction" : "",
|
|
625
|
-
fixedSize: null,
|
|
626
|
-
maxSize: 1
|
|
627
|
-
};
|
|
628
|
-
function decode(bytes2, offset = 0) {
|
|
629
|
-
const firstByte = bytes2[offset];
|
|
630
|
-
if ((firstByte & VERSION_FLAG_MASK) === 0) {
|
|
631
|
-
return ["legacy", offset];
|
|
632
|
-
} else {
|
|
633
|
-
const version = firstByte ^ VERSION_FLAG_MASK;
|
|
634
|
-
return [version, offset + 1];
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
function encode(value) {
|
|
638
|
-
if (value === "legacy") {
|
|
639
|
-
return new Uint8Array();
|
|
640
|
-
}
|
|
641
|
-
if (value < 0 || value > 127) {
|
|
642
|
-
throw new Error(`Transaction version must be in the range [0, 127]. \`${value}\` given.`);
|
|
643
|
-
}
|
|
644
|
-
return new Uint8Array([value | VERSION_FLAG_MASK]);
|
|
645
|
-
}
|
|
646
|
-
function getTransactionVersionDecoder() {
|
|
647
|
-
return {
|
|
648
|
-
...BASE_CONFIG,
|
|
649
|
-
decode
|
|
650
|
-
};
|
|
651
|
-
}
|
|
652
732
|
function getTransactionVersionEncoder() {
|
|
653
|
-
return {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
);
|
|
733
|
+
return createEncoder({
|
|
734
|
+
getSizeFromValue: (value) => value === "legacy" ? 0 : 1,
|
|
735
|
+
maxSize: 1,
|
|
736
|
+
write: (value, bytes, offset) => {
|
|
737
|
+
if (value === "legacy") {
|
|
738
|
+
return offset;
|
|
739
|
+
}
|
|
740
|
+
if (value < 0 || value > 127) {
|
|
741
|
+
throw new Error(`Transaction version must be in the range [0, 127]. \`${value}\` given.`);
|
|
742
|
+
}
|
|
743
|
+
bytes.set([value | VERSION_FLAG_MASK], offset);
|
|
744
|
+
return offset + 1;
|
|
745
|
+
}
|
|
746
|
+
});
|
|
668
747
|
}
|
|
669
|
-
function
|
|
670
|
-
return (
|
|
671
|
-
|
|
672
|
-
|
|
748
|
+
function getTransactionVersionDecoder() {
|
|
749
|
+
return createDecoder({
|
|
750
|
+
maxSize: 1,
|
|
751
|
+
read: (bytes, offset) => {
|
|
752
|
+
const firstByte = bytes[offset];
|
|
753
|
+
if ((firstByte & VERSION_FLAG_MASK) === 0) {
|
|
754
|
+
return ["legacy", offset];
|
|
755
|
+
} else {
|
|
756
|
+
const version = firstByte ^ VERSION_FLAG_MASK;
|
|
757
|
+
return [version, offset + 1];
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
});
|
|
673
761
|
}
|
|
674
762
|
|
|
675
763
|
// src/serializers/message.ts
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
["addressTableLookups", getAddressTableLookupsSerializer()]
|
|
689
|
-
]),
|
|
690
|
-
(value) => {
|
|
691
|
-
if (value.version === "legacy") {
|
|
692
|
-
return value;
|
|
693
|
-
}
|
|
694
|
-
return {
|
|
695
|
-
...value,
|
|
696
|
-
addressTableLookups: value.addressTableLookups ?? []
|
|
697
|
-
};
|
|
764
|
+
function getCompiledMessageLegacyEncoder() {
|
|
765
|
+
return getStructEncoder(getPreludeStructEncoderTuple());
|
|
766
|
+
}
|
|
767
|
+
function getCompiledMessageVersionedEncoder() {
|
|
768
|
+
return mapEncoder(
|
|
769
|
+
getStructEncoder([
|
|
770
|
+
...getPreludeStructEncoderTuple(),
|
|
771
|
+
["addressTableLookups", getAddressTableLookupArrayEncoder()]
|
|
772
|
+
]),
|
|
773
|
+
(value) => {
|
|
774
|
+
if (value.version === "legacy") {
|
|
775
|
+
return value;
|
|
698
776
|
}
|
|
699
|
-
|
|
700
|
-
|
|
777
|
+
return {
|
|
778
|
+
...value,
|
|
779
|
+
addressTableLookups: value.addressTableLookups ?? []
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
);
|
|
701
783
|
}
|
|
702
|
-
function
|
|
703
|
-
return
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
784
|
+
function getPreludeStructEncoderTuple() {
|
|
785
|
+
return [
|
|
786
|
+
["version", getTransactionVersionEncoder()],
|
|
787
|
+
["header", getMessageHeaderEncoder()],
|
|
788
|
+
["staticAccounts", getArrayEncoder(getAddressEncoder(), { size: getShortU16Encoder() })],
|
|
789
|
+
["lifetimeToken", getStringEncoder({ encoding: getBase58Encoder(), size: 32 })],
|
|
790
|
+
["instructions", getArrayEncoder(getInstructionEncoder(), { size: getShortU16Encoder() })]
|
|
791
|
+
];
|
|
710
792
|
}
|
|
711
|
-
function
|
|
793
|
+
function getPreludeStructDecoderTuple() {
|
|
712
794
|
return [
|
|
713
|
-
["version",
|
|
714
|
-
["header",
|
|
715
|
-
[
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
size: shortU16()
|
|
720
|
-
})
|
|
721
|
-
],
|
|
722
|
-
[
|
|
723
|
-
"lifetimeToken",
|
|
724
|
-
string({
|
|
725
|
-
description: __DEV__ ? "A 32-byte token that specifies the lifetime of this transaction (eg. a recent blockhash, or a durable nonce)" : "",
|
|
726
|
-
encoding: base58,
|
|
727
|
-
size: 32
|
|
728
|
-
})
|
|
729
|
-
],
|
|
730
|
-
[
|
|
731
|
-
"instructions",
|
|
732
|
-
array(toSerializer(getInstructionCodec()), {
|
|
733
|
-
description: __DEV__ ? "A compact-array of instructions belonging to this transaction" : "",
|
|
734
|
-
size: shortU16()
|
|
735
|
-
})
|
|
736
|
-
]
|
|
795
|
+
["version", getTransactionVersionDecoder()],
|
|
796
|
+
["header", getMessageHeaderDecoder()],
|
|
797
|
+
["staticAccounts", getArrayDecoder(getAddressDecoder(), { size: getShortU16Decoder() })],
|
|
798
|
+
["lifetimeToken", getStringDecoder({ encoding: getBase58Decoder(), size: 32 })],
|
|
799
|
+
["instructions", getArrayDecoder(getInstructionDecoder(), { size: getShortU16Decoder() })],
|
|
800
|
+
["addressTableLookups", getAddressTableLookupArrayDecoder()]
|
|
737
801
|
];
|
|
738
802
|
}
|
|
739
|
-
function
|
|
740
|
-
return
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
});
|
|
803
|
+
function getAddressTableLookupArrayEncoder() {
|
|
804
|
+
return getArrayEncoder(getAddressTableLookupEncoder(), { size: getShortU16Encoder() });
|
|
805
|
+
}
|
|
806
|
+
function getAddressTableLookupArrayDecoder() {
|
|
807
|
+
return getArrayDecoder(getAddressTableLookupDecoder(), { size: getShortU16Decoder() });
|
|
744
808
|
}
|
|
745
809
|
function getCompiledMessageEncoder() {
|
|
810
|
+
return createEncoder({
|
|
811
|
+
getSizeFromValue: (compiledMessage) => {
|
|
812
|
+
if (compiledMessage.version === "legacy") {
|
|
813
|
+
return getCompiledMessageLegacyEncoder().getSizeFromValue(compiledMessage);
|
|
814
|
+
} else {
|
|
815
|
+
return getCompiledMessageVersionedEncoder().getSizeFromValue(compiledMessage);
|
|
816
|
+
}
|
|
817
|
+
},
|
|
818
|
+
write: (compiledMessage, bytes, offset) => {
|
|
819
|
+
if (compiledMessage.version === "legacy") {
|
|
820
|
+
return getCompiledMessageLegacyEncoder().write(compiledMessage, bytes, offset);
|
|
821
|
+
} else {
|
|
822
|
+
return getCompiledMessageVersionedEncoder().write(compiledMessage, bytes, offset);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
function getCompiledMessageDecoder() {
|
|
828
|
+
return mapDecoder(getStructDecoder(getPreludeStructDecoderTuple()), ({ addressTableLookups, ...restOfMessage }) => {
|
|
829
|
+
if (restOfMessage.version === "legacy" || !addressTableLookups?.length) {
|
|
830
|
+
return restOfMessage;
|
|
831
|
+
}
|
|
832
|
+
return { ...restOfMessage, addressTableLookups };
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
function getCompiledMessageCodec() {
|
|
836
|
+
return combineCodec(getCompiledMessageEncoder(), getCompiledMessageDecoder());
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// src/compile-transaction.ts
|
|
840
|
+
function getCompiledTransaction(transaction) {
|
|
841
|
+
const compiledMessage = compileMessage(transaction);
|
|
842
|
+
let signatures;
|
|
843
|
+
if ("signatures" in transaction) {
|
|
844
|
+
signatures = [];
|
|
845
|
+
for (let ii = 0; ii < compiledMessage.header.numSignerAccounts; ii++) {
|
|
846
|
+
signatures[ii] = transaction.signatures[compiledMessage.staticAccounts[ii]] ?? new Uint8Array(Array(64).fill(0));
|
|
847
|
+
}
|
|
848
|
+
} else {
|
|
849
|
+
signatures = Array(compiledMessage.header.numSignerAccounts).fill(new Uint8Array(Array(64).fill(0)));
|
|
850
|
+
}
|
|
746
851
|
return {
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
serialize
|
|
852
|
+
compiledMessage,
|
|
853
|
+
signatures
|
|
750
854
|
};
|
|
751
855
|
}
|
|
752
856
|
|
|
753
857
|
// src/serializers/transaction.ts
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
return
|
|
858
|
+
function getCompiledTransactionEncoder() {
|
|
859
|
+
return getStructEncoder([
|
|
860
|
+
["signatures", getArrayEncoder(getBytesEncoder({ size: 64 }), { size: getShortU16Encoder() })],
|
|
861
|
+
["compiledMessage", getCompiledMessageEncoder()]
|
|
862
|
+
]);
|
|
863
|
+
}
|
|
864
|
+
function getCompiledTransactionDecoder() {
|
|
865
|
+
return getStructDecoder([
|
|
762
866
|
[
|
|
763
867
|
"signatures",
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
size: shortU16()
|
|
868
|
+
getArrayDecoder(getBytesDecoder({ size: 64 }), {
|
|
869
|
+
size: getShortU16Decoder()
|
|
767
870
|
})
|
|
768
871
|
],
|
|
769
|
-
["compiledMessage",
|
|
770
|
-
])
|
|
872
|
+
["compiledMessage", getCompiledMessageDecoder()]
|
|
873
|
+
]);
|
|
771
874
|
}
|
|
772
875
|
function getTransactionEncoder() {
|
|
773
|
-
return
|
|
774
|
-
...BASE_CONFIG3,
|
|
775
|
-
deserialize: getUnimplementedDecoder("CompiledMessage"),
|
|
776
|
-
serialize: serialize2
|
|
777
|
-
};
|
|
876
|
+
return mapEncoder(getCompiledTransactionEncoder(), getCompiledTransaction);
|
|
778
877
|
}
|
|
779
|
-
function
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
putativeTransactionSignature.length > 88
|
|
785
|
-
) {
|
|
786
|
-
throw new Error("Expected input string to decode to a byte array of length 64.");
|
|
787
|
-
}
|
|
788
|
-
const bytes2 = base58.serialize(putativeTransactionSignature);
|
|
789
|
-
const numBytes = bytes2.byteLength;
|
|
790
|
-
if (numBytes !== 64) {
|
|
791
|
-
throw new Error(`Expected input string to decode to a byte array of length 64. Actual length: ${numBytes}`);
|
|
792
|
-
}
|
|
793
|
-
} catch (e) {
|
|
794
|
-
throw new Error(`\`${putativeTransactionSignature}\` is not a transaction signature`, {
|
|
795
|
-
cause: e
|
|
796
|
-
});
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
function isTransactionSignature(putativeTransactionSignature) {
|
|
800
|
-
if (
|
|
801
|
-
// Lowest value (64 bytes of zeroes)
|
|
802
|
-
putativeTransactionSignature.length < 64 || // Highest value (64 bytes of 255)
|
|
803
|
-
putativeTransactionSignature.length > 88
|
|
804
|
-
) {
|
|
805
|
-
return false;
|
|
806
|
-
}
|
|
807
|
-
const bytes2 = base58.serialize(putativeTransactionSignature);
|
|
808
|
-
const numBytes = bytes2.byteLength;
|
|
809
|
-
if (numBytes !== 64) {
|
|
810
|
-
return false;
|
|
811
|
-
}
|
|
812
|
-
return true;
|
|
878
|
+
function getTransactionDecoder(config) {
|
|
879
|
+
return mapDecoder(
|
|
880
|
+
getCompiledTransactionDecoder(),
|
|
881
|
+
(compiledTransaction) => decompileTransaction(compiledTransaction, config)
|
|
882
|
+
);
|
|
813
883
|
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
const signature = await signBytes(secretKey, wireMessageBytes);
|
|
817
|
-
return signature;
|
|
884
|
+
function getTransactionCodec(config) {
|
|
885
|
+
return combineCodec(getTransactionEncoder(), getTransactionDecoder(config));
|
|
818
886
|
}
|
|
887
|
+
var base58Decoder;
|
|
819
888
|
function getSignatureFromTransaction(transaction) {
|
|
889
|
+
if (!base58Decoder)
|
|
890
|
+
base58Decoder = getBase58Decoder();
|
|
820
891
|
const signatureBytes = transaction.signatures[transaction.feePayer];
|
|
821
892
|
if (!signatureBytes) {
|
|
822
893
|
throw new Error(
|
|
823
894
|
"Could not determine this transaction's signature. Make sure that the transaction has been signed by its fee payer."
|
|
824
895
|
);
|
|
825
896
|
}
|
|
826
|
-
const
|
|
827
|
-
return
|
|
897
|
+
const transactionSignature = base58Decoder.decode(signatureBytes);
|
|
898
|
+
return transactionSignature;
|
|
828
899
|
}
|
|
829
|
-
async function
|
|
900
|
+
async function partiallySignTransaction(keyPairs, transaction) {
|
|
830
901
|
const compiledMessage = compileMessage(transaction);
|
|
831
902
|
const nextSignatures = "signatures" in transaction ? { ...transaction.signatures } : {};
|
|
903
|
+
const wireMessageBytes = getCompiledMessageEncoder().encode(compiledMessage);
|
|
832
904
|
const publicKeySignaturePairs = await Promise.all(
|
|
833
905
|
keyPairs.map(
|
|
834
|
-
(keyPair) => Promise.all([
|
|
835
|
-
getAddressFromPublicKey(keyPair.publicKey),
|
|
836
|
-
getCompiledMessageSignature(compiledMessage, keyPair.privateKey)
|
|
837
|
-
])
|
|
906
|
+
(keyPair) => Promise.all([getAddressFromPublicKey(keyPair.publicKey), signBytes(keyPair.privateKey, wireMessageBytes)])
|
|
838
907
|
)
|
|
839
908
|
);
|
|
840
909
|
for (const [signerPublicKey, signature] of publicKeySignaturePairs) {
|
|
@@ -847,17 +916,30 @@ async function signTransaction(keyPairs, transaction) {
|
|
|
847
916
|
Object.freeze(out);
|
|
848
917
|
return out;
|
|
849
918
|
}
|
|
850
|
-
function
|
|
851
|
-
|
|
852
|
-
|
|
919
|
+
async function signTransaction(keyPairs, transaction) {
|
|
920
|
+
const out = await partiallySignTransaction(keyPairs, transaction);
|
|
921
|
+
assertTransactionIsFullySigned(out);
|
|
922
|
+
Object.freeze(out);
|
|
923
|
+
return out;
|
|
853
924
|
}
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
const
|
|
858
|
-
{
|
|
859
|
-
|
|
925
|
+
function assertTransactionIsFullySigned(transaction) {
|
|
926
|
+
const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => i.accounts?.filter((a) => isSignerRole(a.role)) ?? []).map((a) => a.address);
|
|
927
|
+
const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]);
|
|
928
|
+
const missingSigs = [];
|
|
929
|
+
requiredSigners.forEach((address) => {
|
|
930
|
+
if (!transaction.signatures[address]) {
|
|
931
|
+
missingSigs.push(address);
|
|
932
|
+
}
|
|
933
|
+
});
|
|
934
|
+
if (missingSigs.length > 0) {
|
|
935
|
+
throw new Error("Transaction is missing signatures for addresses: " + missingSigs.join(", "));
|
|
860
936
|
}
|
|
861
937
|
}
|
|
938
|
+
function getBase64EncodedWireTransaction(transaction) {
|
|
939
|
+
const wireTransactionBytes = getTransactionEncoder().encode(transaction);
|
|
940
|
+
return getBase64Decoder().decode(wireTransactionBytes);
|
|
941
|
+
}
|
|
862
942
|
|
|
863
|
-
export { appendTransactionInstruction, assertIsBlockhash, assertIsDurableNonceTransaction,
|
|
943
|
+
export { appendTransactionInstruction, assertIsBlockhash, assertIsDurableNonceTransaction, assertIsTransactionWithBlockhashLifetime, assertTransactionIsFullySigned, compileMessage, createTransaction, decompileTransaction, getBase64EncodedWireTransaction, getCompiledMessageCodec, getCompiledMessageDecoder, getCompiledMessageEncoder, getCompiledTransactionDecoder, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, isAdvanceNonceAccountInstruction, partiallySignTransaction, prependTransactionInstruction, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, setTransactionLifetimeUsingDurableNonce, signTransaction };
|
|
944
|
+
//# sourceMappingURL=out.js.map
|
|
945
|
+
//# sourceMappingURL=index.node.js.map
|